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" 15a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "clang/Basic/Diagnostic.h" 16c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#include "clang/Basic/FileManager.h" 17c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#include "clang/Basic/IdentifierTable.h" 1855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/HeaderMap.h" 1955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/HeaderSearchOptions.h" 2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/Lexer.h" 215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/SmallString.h" 22eabea45e23abc07e917f0d4bce15054ce75623efTed Kremenek#include "llvm/Support/Capacity.h" 2355fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/FileSystem.h" 2455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/Path.h" 253daed52a57d03765223021f5f921bdc280c8f3ccChris Lattner#include <cstdio> 263cc6277a3dd4986af6422e41db18ba6efddbd800Douglas Gregor#if defined(LLVM_ON_UNIX) 27adeb7822cb7947194fef0e12d2d6583ccb8240b5Dmitri Gribenko#include <limits.h> 283cc6277a3dd4986af6422e41db18ba6efddbd800Douglas Gregor#endif 295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 318c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorconst IdentifierInfo * 328c5a760b82e73ed90b560090772db97e2ae27b09Douglas GregorHeaderFileInfo::getControllingMacro(ExternalIdentifierLookup *External) { 338c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor if (ControllingMacro) 348c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor return ControllingMacro; 358c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 368c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor if (!ControllingMacroID || !External) 378c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor return 0; 388c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 398c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor ControllingMacro = External->GetIdentifier(ControllingMacroID); 408c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor return ControllingMacro; 418c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor} 428c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 43cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas GregorExternalHeaderFileInfoSource::~ExternalHeaderFileInfoSource() {} 44cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 45cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri GribenkoHeaderSearch::HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts, 46c042edd54face617a3b9d0b4b9d5a3ff229d0f48Douglas Gregor FileManager &FM, DiagnosticsEngine &Diags, 47dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor const LangOptions &LangOpts, 48dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor const TargetInfo *Target) 49c042edd54face617a3b9d0b4b9d5a3ff229d0f48Douglas Gregor : HSOpts(HSOpts), FileMgr(FM), FrameworkMap(64), 5055ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis ModMap(FileMgr, *Diags.getClient(), LangOpts, Target, *this) 518e23806863721495f9e1f84aed614f7afba774a3Douglas Gregor{ 5274a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber AngledDirIdx = 0; 535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SystemDirIdx = 0; 545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NoCurDirSearch = false; 551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 568c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor ExternalLookup = 0; 57cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor ExternalSource = 0; 585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumIncluded = 0; 595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumMultiIncludeFileOptzn = 0; 605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumFrameworkLookups = NumSubFrameworkLookups = 0; 615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 63822da61b74ce14e89b3fa8774db18c833aa5748bChris LattnerHeaderSearch::~HeaderSearch() { 64822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner // Delete headermaps. 65822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i) 66822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner delete HeaderMaps[i].second; 67822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner} 681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid HeaderSearch::PrintStats() { 705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "\n*** HeaderSearch Stats:\n"); 715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "%d files tracked.\n", (int)FileInfo.size()); 725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0; 735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer for (unsigned i = 0, e = FileInfo.size(); i != e; ++i) { 745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumOnceOnlyFiles += FileInfo[i].isImport; 755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (MaxNumIncludes < FileInfo[i].NumIncludes) 765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer MaxNumIncludes = FileInfo[i].NumIncludes; 775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1; 785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d #import/#pragma once files.\n", NumOnceOnlyFiles); 805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d included exactly once.\n", NumSingleIncludedFiles); 815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d max times a file is included.\n", MaxNumIncludes); 821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d #include/#include_next/#import.\n", NumIncluded); 845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d #includes skipped due to" 855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer " the multi-include optimization.\n", NumMultiIncludeFileOptzn); 861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "%d framework lookups.\n", NumFrameworkLookups); 885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "%d subframework lookups.\n", NumSubFrameworkLookups); 895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 91822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner/// CreateHeaderMap - This method returns a HeaderMap for the specified 92bed28ac1d1463adca3ecf24fca5c30646fa9dbb2Sylvestre Ledru/// FileEntry, uniquing them through the 'HeaderMaps' datastructure. 931bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattnerconst HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) { 94822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner // We expect the number of headermaps to be small, and almost always empty. 95df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner // If it ever grows, use of a linear search should be re-evaluated. 96822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner if (!HeaderMaps.empty()) { 97822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i) 98df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner // Pointer equality comparison of FileEntries works because they are 99df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner // already uniqued by inode. 1001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (HeaderMaps[i].first == FE) 101822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner return HeaderMaps[i].second; 102822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner } 1031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 10439b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner if (const HeaderMap *HM = HeaderMap::Create(FE, FileMgr)) { 105822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner HeaderMaps.push_back(std::make_pair(FE, HM)); 106822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner return HM; 107822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner } 1081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 109822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner return 0; 110822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner} 111822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner 112e434ec71fccfe078906403affd641f709702d598Douglas Gregorstd::string HeaderSearch::getModuleFileName(Module *Module) { 1139a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor // If we don't have a module cache path, we can't do anything. 114e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (ModuleCachePath.empty()) 115e434ec71fccfe078906403affd641f709702d598Douglas Gregor return std::string(); 116e434ec71fccfe078906403affd641f709702d598Douglas Gregor 117e434ec71fccfe078906403affd641f709702d598Douglas Gregor 118f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<256> Result(ModuleCachePath); 119e434ec71fccfe078906403affd641f709702d598Douglas Gregor llvm::sys::path::append(Result, Module->getTopLevelModule()->Name + ".pcm"); 120e434ec71fccfe078906403affd641f709702d598Douglas Gregor return Result.str().str(); 121e434ec71fccfe078906403affd641f709702d598Douglas Gregor} 122e434ec71fccfe078906403affd641f709702d598Douglas Gregor 123e434ec71fccfe078906403affd641f709702d598Douglas Gregorstd::string HeaderSearch::getModuleFileName(StringRef ModuleName) { 124e434ec71fccfe078906403affd641f709702d598Douglas Gregor // If we don't have a module cache path, we can't do anything. 125e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (ModuleCachePath.empty()) 126e434ec71fccfe078906403affd641f709702d598Douglas Gregor return std::string(); 1276e975c4517958bcc11c834336d340797356058dbDouglas Gregor 128e434ec71fccfe078906403affd641f709702d598Douglas Gregor 129f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<256> Result(ModuleCachePath); 130e434ec71fccfe078906403affd641f709702d598Douglas Gregor llvm::sys::path::append(Result, ModuleName + ".pcm"); 131e434ec71fccfe078906403affd641f709702d598Douglas Gregor return Result.str().str(); 132e434ec71fccfe078906403affd641f709702d598Douglas Gregor} 133e434ec71fccfe078906403affd641f709702d598Douglas Gregor 134e434ec71fccfe078906403affd641f709702d598Douglas GregorModule *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) { 135cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // Look in the module map to determine if there is a module by this name. 136e434ec71fccfe078906403affd641f709702d598Douglas Gregor Module *Module = ModMap.findModule(ModuleName); 137e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (Module || !AllowSearch) 138e434ec71fccfe078906403affd641f709702d598Douglas Gregor return Module; 139e434ec71fccfe078906403affd641f709702d598Douglas Gregor 1407005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Look through the various header search paths to load any available module 141e434ec71fccfe078906403affd641f709702d598Douglas Gregor // maps, searching for a module map that describes this module. 142e434ec71fccfe078906403affd641f709702d598Douglas Gregor for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { 143e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (SearchDirs[Idx].isFramework()) { 144e434ec71fccfe078906403affd641f709702d598Douglas Gregor // Search for or infer a module map for a framework. 145f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> FrameworkDirName; 146e434ec71fccfe078906403affd641f709702d598Douglas Gregor FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName(); 147e434ec71fccfe078906403affd641f709702d598Douglas Gregor llvm::sys::path::append(FrameworkDirName, ModuleName + ".framework"); 148e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (const DirectoryEntry *FrameworkDir 149e434ec71fccfe078906403affd641f709702d598Douglas Gregor = FileMgr.getDirectory(FrameworkDirName)) { 150e434ec71fccfe078906403affd641f709702d598Douglas Gregor bool IsSystem 151e434ec71fccfe078906403affd641f709702d598Douglas Gregor = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User; 152e434ec71fccfe078906403affd641f709702d598Douglas Gregor Module = loadFrameworkModule(ModuleName, FrameworkDir, IsSystem); 153cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (Module) 154cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor break; 155cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 156e434ec71fccfe078906403affd641f709702d598Douglas Gregor } 157e434ec71fccfe078906403affd641f709702d598Douglas Gregor 158e434ec71fccfe078906403affd641f709702d598Douglas Gregor // FIXME: Figure out how header maps and module maps will work together. 159e434ec71fccfe078906403affd641f709702d598Douglas Gregor 160e434ec71fccfe078906403affd641f709702d598Douglas Gregor // Only deal with normal search directories. 161e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (!SearchDirs[Idx].isNormalDir()) 162e434ec71fccfe078906403affd641f709702d598Douglas Gregor continue; 1638f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor 1648f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory(); 165e434ec71fccfe078906403affd641f709702d598Douglas Gregor // Search for a module map file in this directory. 1668f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor if (loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem) 1678f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor == LMM_NewlyLoaded) { 168e434ec71fccfe078906403affd641f709702d598Douglas Gregor // We just loaded a module map file; check whether the module is 169e434ec71fccfe078906403affd641f709702d598Douglas Gregor // available now. 170e434ec71fccfe078906403affd641f709702d598Douglas Gregor Module = ModMap.findModule(ModuleName); 171e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (Module) 172e434ec71fccfe078906403affd641f709702d598Douglas Gregor break; 173e434ec71fccfe078906403affd641f709702d598Douglas Gregor } 174e434ec71fccfe078906403affd641f709702d598Douglas Gregor 175e434ec71fccfe078906403affd641f709702d598Douglas Gregor // Search for a module map in a subdirectory with the same name as the 176e434ec71fccfe078906403affd641f709702d598Douglas Gregor // module. 177f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> NestedModuleMapDirName; 178e434ec71fccfe078906403affd641f709702d598Douglas Gregor NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName(); 179e434ec71fccfe078906403affd641f709702d598Douglas Gregor llvm::sys::path::append(NestedModuleMapDirName, ModuleName); 1808f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor if (loadModuleMapFile(NestedModuleMapDirName, IsSystem) == LMM_NewlyLoaded){ 181e434ec71fccfe078906403affd641f709702d598Douglas Gregor // If we just loaded a module map file, look for the module again. 182e434ec71fccfe078906403affd641f709702d598Douglas Gregor Module = ModMap.findModule(ModuleName); 183e434ec71fccfe078906403affd641f709702d598Douglas Gregor if (Module) 184e434ec71fccfe078906403affd641f709702d598Douglas Gregor break; 185cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 186cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor 187cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor // If we've already performed the exhaustive search for module maps in this 188cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor // search directory, don't do it again. 189cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor if (SearchDirs[Idx].haveSearchedAllModuleMaps()) 190cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor continue; 191cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor 192cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor // Load all module maps in the immediate subdirectories of this search 193cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor // directory. 194cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor loadSubdirectoryModuleMaps(SearchDirs[Idx]); 195cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor 196cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor // Look again for the module. 197cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor Module = ModMap.findModule(ModuleName); 198cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor if (Module) 199cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor break; 200cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 201cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor 202e434ec71fccfe078906403affd641f709702d598Douglas Gregor return Module; 2039a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor} 2049a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor 205df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner//===----------------------------------------------------------------------===// 206df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner// File lookup within a DirectoryLookup scope 207df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner//===----------------------------------------------------------------------===// 208df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner 2093af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner/// getName - Return the directory or filename corresponding to this lookup 2103af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner/// object. 2113af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattnerconst char *DirectoryLookup::getName() const { 2123af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner if (isNormalDir()) 2133af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner return getDir()->getName(); 2143af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner if (isFramework()) 2153af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner return getFrameworkDir()->getName(); 2163af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner assert(isHeaderMap() && "Unknown DirectoryLookup"); 2173af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner return getHeaderMap()->getFileName(); 2183af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner} 2193af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner 2203af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner 221df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner/// LookupFile - Lookup the specified file in this search path, returning it 222df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner/// if it exists or returning null if not. 223b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruthconst FileEntry *DirectoryLookup::LookupFile( 2245f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Filename, 2257412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek HeaderSearch &HS, 2265f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> *SearchPath, 227fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SmallVectorImpl<char> *RelativePath, 228bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl ModuleMap::KnownHeader *SuggestedModule, 22985ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar bool &InUserSpecifiedSystemFramework) const { 23085ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar InUserSpecifiedSystemFramework = false; 23185ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar 232f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<1024> TmpDir; 233afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner if (isNormalDir()) { 234afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // Concatenate the requested file onto the directory. 235a6e023c4491a8a8116c11783f4e81c7bd172f88dEli Friedman TmpDir = getDir()->getName(); 236a6e023c4491a8a8116c11783f4e81c7bd172f88dEli Friedman llvm::sys::path::append(TmpDir, Filename); 2377412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) { 2385f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef SearchPathRef(getDir()->getName()); 2397412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 2407412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 2417412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 2427412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (RelativePath != NULL) { 2437412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 2447412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin(), Filename.end()); 2457412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 246a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 247a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // If we have a module map that might map this header, load it and 248a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // check whether we'll have a suggestion for a module. 2498f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor if (SuggestedModule && 2508f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor HS.hasModuleMap(TmpDir, getDir(), isSystemHeaderDirectory())) { 251a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor const FileEntry *File = HS.getFileMgr().getFile(TmpDir.str(), 252a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /*openFile=*/false); 253a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!File) 254a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return File; 255a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 256a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // If there is a module that corresponds to this header, 257a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // suggest it. 2585e3f9223db88227d6d21679c613b139d8160186dDouglas Gregor *SuggestedModule = HS.findModuleForHeader(File); 259a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return File; 260a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 261a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 2623cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis return HS.getFileMgr().getFile(TmpDir.str(), /*openFile=*/true); 263afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner } 2641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 265afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner if (isFramework()) 266fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath, 26785ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar SuggestedModule, InUserSpecifiedSystemFramework); 2681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 269b09e71fd52d0e7fdf3e88b1df72ea0cee5d9b37bChris Lattner assert(isHeaderMap() && "Unknown directory lookup"); 2707412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek const FileEntry * const Result = getHeaderMap()->LookupFile( 2717412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek Filename, HS.getFileMgr()); 2727412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (Result) { 2737412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) { 2745f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef SearchPathRef(getName()); 2757412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 2767412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 2777412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 2787412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (RelativePath != NULL) { 2797412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 2807412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin(), Filename.end()); 2817412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 2827412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 2837412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek return Result; 284df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner} 285df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner 2867005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor/// \brief Given a framework directory, find the top-most framework directory. 2877005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor/// 2887005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor/// \param FileMgr The file manager to use for directory lookups. 2897005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor/// \param DirName The name of the framework directory. 2907005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor/// \param SubmodulePath Will be populated with the submodule path from the 2917005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor/// returned top-level module to the originally named framework. 2927005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregorstatic const DirectoryEntry * 2937005b907ea159c8e74e81f85269777429bc18d3cDouglas GregorgetTopFrameworkDir(FileManager &FileMgr, StringRef DirName, 2947005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor SmallVectorImpl<std::string> &SubmodulePath) { 2957005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor assert(llvm::sys::path::extension(DirName) == ".framework" && 2967005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor "Not a framework directory"); 2977005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 2987005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Note: as an egregious but useful hack we use the real path here, because 2997005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // frameworks moving between top-level frameworks to embedded frameworks tend 3007005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // to be symlinked, and we base the logical structure of modules on the 3017005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // physical layout. In particular, we need to deal with crazy includes like 3027005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // 3037005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // #include <Foo/Frameworks/Bar.framework/Headers/Wibble.h> 3047005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // 3057005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // where 'Bar' used to be embedded in 'Foo', is now a top-level framework 3067005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // which one should access with, e.g., 3077005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // 3087005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // #include <Bar/Wibble.h> 3097005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // 3107005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Similar issues occur when a top-level framework has moved into an 3117005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // embedded framework. 3127005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor const DirectoryEntry *TopFrameworkDir = FileMgr.getDirectory(DirName); 313713b7c011869f177dc76e6df4f7f44b1bd073bb0Douglas Gregor DirName = FileMgr.getCanonicalName(TopFrameworkDir); 3147005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor do { 3157005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Get the parent directory name. 3167005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor DirName = llvm::sys::path::parent_path(DirName); 3177005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (DirName.empty()) 3187005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor break; 3197005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 3207005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Determine whether this directory exists. 3217005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor const DirectoryEntry *Dir = FileMgr.getDirectory(DirName); 3227005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (!Dir) 3237005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor break; 3247005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 3257005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // If this is a framework directory, then we're a subframework of this 3267005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // framework. 3277005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (llvm::sys::path::extension(DirName) == ".framework") { 3287005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor SubmodulePath.push_back(llvm::sys::path::stem(DirName)); 3297005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor TopFrameworkDir = Dir; 3307005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor } 3317005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor } while (true); 3327005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 3337005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor return TopFrameworkDir; 3347005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor} 335df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner 336afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner/// DoFrameworkLookup - Do a lookup of the specified file in the current 337afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner/// DirectoryLookup, which is a framework directory. 338b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruthconst FileEntry *DirectoryLookup::DoFrameworkLookup( 3395f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Filename, 3407412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek HeaderSearch &HS, 3415f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> *SearchPath, 342fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SmallVectorImpl<char> *RelativePath, 343bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl ModuleMap::KnownHeader *SuggestedModule, 34485ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar bool &InUserSpecifiedSystemFramework) const 345fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor{ 346afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner FileManager &FileMgr = HS.getFileMgr(); 3471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Framework names must have a '/' in the filename. 349a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner size_t SlashPos = Filename.find('/'); 3505f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner if (SlashPos == StringRef::npos) return 0; 3511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 352afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // Find out if this is the home for the specified framework, by checking 3539ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar // HeaderSearch. Possible answers are yes/no and unknown. 3549ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar HeaderSearch::FrameworkCacheEntry &CacheEntry = 355a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner HS.LookupFrameworkCache(Filename.substr(0, SlashPos)); 3561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 357afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // If it is known and in some other directory, fail. 3589ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar if (CacheEntry.Directory && CacheEntry.Directory != getFrameworkDir()) 3595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return 0; 3601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 361afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // Otherwise, construct the path to this framework dir. 3621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // FrameworkName = "/System/Library/Frameworks/" 364f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<1024> FrameworkName; 365afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner FrameworkName += getFrameworkDir()->getName(); 3665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FrameworkName.empty() || FrameworkName.back() != '/') 3675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName.push_back('/'); 3681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // FrameworkName = "/System/Library/Frameworks/Cocoa" 3702821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor StringRef ModuleName(Filename.begin(), SlashPos); 3712821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor FrameworkName += ModuleName; 3721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/" 3745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName += ".framework/"; 3751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3769ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar // If the cache entry was unresolved, populate it now. 3779ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar if (CacheEntry.Directory == 0) { 378afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner HS.IncrementFrameworkLookupCount(); 3791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the framework dir doesn't exist, we fail. 38185ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str()); 38285ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar if (Dir == 0) return 0; 3831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, if it does, remember that this is the right direntry for this 3855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // framework. 3869ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar CacheEntry.Directory = getFrameworkDir(); 38785ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar 38885ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar // If this is a user search directory, check if the framework has been 38985ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar // user-specified as a system framework. 39085ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar if (getDirCharacteristic() == SrcMgr::C_User) { 39185ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar SmallString<1024> SystemFrameworkMarker(FrameworkName); 39285ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar SystemFrameworkMarker += ".system_framework"; 39385ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar if (llvm::sys::fs::exists(SystemFrameworkMarker.str())) { 39485ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar CacheEntry.IsUserSpecifiedSystemFramework = true; 39585ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar } 39685ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar } 3975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 3981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 39985ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar // Set the 'user-specified system framework' flag. 40085ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework; 40185ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar 4027412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (RelativePath != NULL) { 4037412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 4047412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); 4057412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 4062821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 4075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h" 4085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned OrigSize = FrameworkName.size(); 4091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName += "Headers/"; 4117412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 4127412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) { 4137412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 4147412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek // Without trailing '/'. 4157412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1); 4167412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 4177412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 418a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end()); 4197005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor const FileEntry *FE = FileMgr.getFile(FrameworkName.str(), 4207005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor /*openFile=*/!SuggestedModule); 4217005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (!FE) { 4227005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h" 4237005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor const char *Private = "Private"; 4247005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor FrameworkName.insert(FrameworkName.begin()+OrigSize, Private, 4257005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor Private+strlen(Private)); 4267005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (SearchPath != NULL) 4277005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor SearchPath->insert(SearchPath->begin()+OrigSize, Private, 4287005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor Private+strlen(Private)); 4297005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 4307005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor FE = FileMgr.getFile(FrameworkName.str(), /*openFile=*/!SuggestedModule); 431b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth } 4321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4337005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // If we found the header and are allowed to suggest a module, do so now. 4347005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (FE && SuggestedModule) { 4357005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Find the framework in which this header occurs. 4367005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor StringRef FrameworkPath = FE->getName(); 4377005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor bool FoundFramework = false; 4387005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor do { 4397005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Get the parent directory name. 4407005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor FrameworkPath = llvm::sys::path::parent_path(FrameworkPath); 4417005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (FrameworkPath.empty()) 4427005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor break; 4437005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 4447005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Determine whether this directory exists. 4457005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkPath); 4467005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (!Dir) 4477005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor break; 4487005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 4497005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // If this is a framework directory, then we're a subframework of this 4507005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // framework. 4517005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (llvm::sys::path::extension(FrameworkPath) == ".framework") { 4527005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor FoundFramework = true; 4537005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor break; 4547005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor } 4557005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor } while (true); 4567005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 4577005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (FoundFramework) { 4587005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Find the top-level framework based on this framework. 4597005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor SmallVector<std::string, 4> SubmodulePath; 4607005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor const DirectoryEntry *TopFrameworkDir 4617005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor = ::getTopFrameworkDir(FileMgr, FrameworkPath, SubmodulePath); 4627005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 4637005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Determine the name of the top-level framework. 4647005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName()); 4657005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor 4667005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Load this framework module. If that succeeds, find the suggested module 4677005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // for this header, if any. 4687005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor bool IsSystem = getDirCharacteristic() != SrcMgr::C_User; 4697005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (HS.loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystem)) { 4707005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor *SuggestedModule = HS.findModuleForHeader(FE); 4717005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor } 4727005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor } else { 4737005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor *SuggestedModule = HS.findModuleForHeader(FE); 4747005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor } 4757005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor } 476fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor return FE; 4775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 4785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 479dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregorvoid HeaderSearch::setTarget(const TargetInfo &Target) { 480dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor ModMap.setTarget(Target); 481dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor} 482dc58aa71026cce539ca9b5c2c52cc4efc7bd77feDouglas Gregor 483df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner 484afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner//===----------------------------------------------------------------------===// 485afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner// Header File Location. 486afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner//===----------------------------------------------------------------------===// 487afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner 488afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner 489853519cd45716c0a0923a7b65ce7aca63cb4dae4James Dennett/// LookupFile - Given a "foo" or \<foo> reference, look up the indicated file, 4905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// return null on failure. isAngled indicates whether the file reference is 491853519cd45716c0a0923a7b65ce7aca63cb4dae4James Dennett/// for system \#include's or not (i.e. using <> instead of ""). CurFileEnt, if 492853519cd45716c0a0923a7b65ce7aca63cb4dae4James Dennett/// non-null, indicates where the \#including file is, in case a relative search 49310fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor/// is needed. 494b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruthconst FileEntry *HeaderSearch::LookupFile( 4955f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Filename, 496b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth bool isAngled, 497b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth const DirectoryLookup *FromDir, 498b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth const DirectoryLookup *&CurDir, 499b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth const FileEntry *CurFileEnt, 5005f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> *SearchPath, 501fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SmallVectorImpl<char> *RelativePath, 502bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl ModuleMap::KnownHeader *SuggestedModule, 5031c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor bool SkipCache) 504fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor{ 505fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor if (SuggestedModule) 506bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl *SuggestedModule = ModuleMap::KnownHeader(); 507fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor 5085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If 'Filename' is absolute, check to see if it exists and no searching. 509256053b31e697fdf0cc48f17d621c82fc3b8dff0Michael J. Spencer if (llvm::sys::path::is_absolute(Filename)) { 5105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer CurDir = 0; 5115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this was an #include_next "/absolute/file", fail. 5135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FromDir) return 0; 5141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5157412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) 5167412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 5177412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (RelativePath != NULL) { 5187412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 5197412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin(), Filename.end()); 5207412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 5215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, just return the file. 5223cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis return FileMgr.getFile(Filename, /*openFile=*/true); 5235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 5241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 52565e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor // Unless disabled, check to see if the file is in the #includer's 52610fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // directory. This has to be based on CurFileEnt, not CurDir, because 52710fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // CurFileEnt could be a #include of a subdirectory (#include "foo/bar.h") and 528df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner // a subsequent include of "baz.h" should resolve to "whatever/foo/baz.h". 529df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner // This search is not done for <> headers. 53010fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor if (CurFileEnt && !isAngled && !NoCurDirSearch) { 531f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<1024> TmpDir; 53210fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // Concatenate the requested file onto the directory. 53310fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // FIXME: Portability. Filename concatenation should be in sys::Path. 53410fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor TmpDir += CurFileEnt->getDir()->getName(); 53510fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor TmpDir.push_back('/'); 53610fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor TmpDir.append(Filename.begin(), Filename.end()); 5373cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis if (const FileEntry *FE = FileMgr.getFile(TmpDir.str(),/*openFile=*/true)) { 5385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Leave CurDir unset. 53910fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // This file is a system header or C++ unfriendly if the old file is. 54010fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // 54121efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor // Note that we only use one of FromHFI/ToHFI at once, due to potential 54221efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor // reallocation of the underlying vector potentially making the first 54321efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor // reference binding dangling. 54421efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor HeaderFileInfo &FromHFI = getFileInfo(CurFileEnt); 54521efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor unsigned DirInfo = FromHFI.DirInfo; 54621efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor bool IndexHeaderMapHeader = FromHFI.IndexHeaderMapHeader; 54721efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor StringRef Framework = FromHFI.Framework; 54821efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor 54921efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor HeaderFileInfo &ToHFI = getFileInfo(FE); 55021efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor ToHFI.DirInfo = DirInfo; 55121efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader; 55221efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor ToHFI.Framework = Framework; 55321efbb606fe905b0f5a479b7b3e6d79023cb82eeDouglas Gregor 5547412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) { 5555f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef SearchPathRef(CurFileEnt->getDir()->getName()); 5567412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 5577412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 5587412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 5597412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (RelativePath != NULL) { 5607412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 5617412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin(), Filename.end()); 5627412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 5635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return FE; 5645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 5655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 5661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer CurDir = 0; 5685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this is a system #include, ignore the user #include locs. 57074a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber unsigned i = isAngled ? AngledDirIdx : 0; 5711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this is a #include_next request, start searching after the directory the 5735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // file was found in. 5745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FromDir) 5755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer i = FromDir-&SearchDirs[0]; 5761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5779960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // Cache all of the lookups performed by this method. Many headers are 5789960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // multiply included, and the "pragma once" optimization prevents them from 5799960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // being relex/pp'd, but they would still have to search through a 5809960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // (potentially huge) series of SearchDirs to find it. 5819960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner std::pair<unsigned, unsigned> &CacheLookup = 582a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner LookupFileCache.GetOrCreateValue(Filename).getValue(); 5839960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner 5849960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // If the entry has been previously looked up, the first value will be 5859960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // non-zero. If the value is equal to i (the start point of our search), then 5869960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // this is a matching hit. 5871c2e9332fa69727425a3a2b912e36e2ab62083f8Douglas Gregor if (!SkipCache && CacheLookup.first == i+1) { 5889960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // Skip querying potentially lots of directories for this lookup. 5899960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner i = CacheLookup.second; 5909960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner } else { 5919960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // Otherwise, this is the first query, or the previous query didn't match 5929960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // our search start. We will fill in our found location below, so prime the 5939960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // start point value. 5949960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner CacheLookup.first = i+1; 5959960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner } 5961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Check each directory in sequence to see if it contains this file. 5985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer for (; i != SearchDirs.size(); ++i) { 59985ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar bool InUserSpecifiedSystemFramework = false; 6001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const FileEntry *FE = 601fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath, 60285ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar SuggestedModule, InUserSpecifiedSystemFramework); 603afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner if (!FE) continue; 6041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 605afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner CurDir = &SearchDirs[i]; 6061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 607afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // This file is a system header or C++ unfriendly if the dir is. 60865e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor HeaderFileInfo &HFI = getFileInfo(FE); 60965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor HFI.DirInfo = CurDir->getDirCharacteristic(); 61065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor 61185ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar // If the directory characteristic is User but this framework was 61285ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar // user-specified to be treated as a system framework, promote the 61385ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar // characteristic. 61485ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar if (HFI.DirInfo == SrcMgr::C_User && InUserSpecifiedSystemFramework) 61585ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar HFI.DirInfo = SrcMgr::C_System; 61685ff9693b178658f9d8af7be30a086fb1ab81fddDaniel Dunbar 617f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith // If the filename matches a known system header prefix, override 618f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith // whether the file is a system header. 6194ef2f6a95146423a1947b98458cc95c00a8b3ebdRichard Trieu for (unsigned j = SystemHeaderPrefixes.size(); j; --j) { 6204ef2f6a95146423a1947b98458cc95c00a8b3ebdRichard Trieu if (Filename.startswith(SystemHeaderPrefixes[j-1].first)) { 6214ef2f6a95146423a1947b98458cc95c00a8b3ebdRichard Trieu HFI.DirInfo = SystemHeaderPrefixes[j-1].second ? SrcMgr::C_System 622f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith : SrcMgr::C_User; 623f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith break; 624f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith } 625f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith } 626f122a138e39dbb29162abfa9a3d44091d8efa7afRichard Smith 62765e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor // If this file is found in a header map and uses the framework style of 62865e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor // includes, then this header is part of a framework we're building. 62965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor if (CurDir->isIndexHeaderMap()) { 63065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor size_t SlashPos = Filename.find('/'); 63165e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor if (SlashPos != StringRef::npos) { 63265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor HFI.IndexHeaderMapHeader = 1; 63365e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor HFI.Framework = getUniqueFrameworkName(StringRef(Filename.begin(), 63465e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor SlashPos)); 63565e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor } 63665e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor } 63765e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor 638afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // Remember this location for the next lookup we do. 639afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner CacheLookup.second = i; 640afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner return FE; 6415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 6421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6432c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor // If we are including a file with a quoted include "foo.h" from inside 6442c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor // a header in a framework that is currently being built, and we couldn't 6452c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor // resolve "foo.h" any other way, change the include to <Foo/foo.h>, where 6462c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor // "Foo" is the name of the framework in which the including header was found. 6472c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor if (CurFileEnt && !isAngled && Filename.find('/') == StringRef::npos) { 6482c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor HeaderFileInfo &IncludingHFI = getFileInfo(CurFileEnt); 6492c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor if (IncludingHFI.IndexHeaderMapHeader) { 650f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> ScratchFilename; 6512c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor ScratchFilename += IncludingHFI.Framework; 6522c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor ScratchFilename += '/'; 6532c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor ScratchFilename += Filename; 6542c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor 6552c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor const FileEntry *Result = LookupFile(ScratchFilename, /*isAngled=*/true, 6562c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor FromDir, CurDir, CurFileEnt, 657fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SearchPath, RelativePath, 658fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SuggestedModule); 6592c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor std::pair<unsigned, unsigned> &CacheLookup 6602c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor = LookupFileCache.GetOrCreateValue(Filename).getValue(); 6612c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor CacheLookup.second 6622c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor = LookupFileCache.GetOrCreateValue(ScratchFilename).getValue().second; 6632c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor return Result; 6642c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor } 6652c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor } 6662c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor 6679960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // Otherwise, didn't find it. Remember we didn't find this. 6689960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner CacheLookup.second = SearchDirs.size(); 6695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return 0; 6705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 6715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 6725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// LookupSubframeworkHeader - Look up a subframework for the specified 673853519cd45716c0a0923a7b65ce7aca63cb4dae4James Dennett/// \#include file. For example, if \#include'ing <HIToolbox/HIToolbox.h> from 6745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox 6755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is a subframework within Carbon.framework. If so, return the FileEntry 6765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// for the designated file, otherwise return null. 6775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerconst FileEntry *HeaderSearch:: 6785f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerLookupSubframeworkHeader(StringRef Filename, 679b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth const FileEntry *ContextFileEnt, 6805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> *SearchPath, 6811b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor SmallVectorImpl<char> *RelativePath, 682bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl ModuleMap::KnownHeader *SuggestedModule) { 6839415a0cc93117b69add4e1dc0f11146f3479ee1aChris Lattner assert(ContextFileEnt && "No context file?"); 6841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Framework names must have a '/' in the filename. Find it. 686efda0e8705e79a4b7de9f18b0d4618515f9e4bccDouglas Gregor // FIXME: Should we permit '\' on Windows? 687a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner size_t SlashPos = Filename.find('/'); 6885f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner if (SlashPos == StringRef::npos) return 0; 6891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Look up the base framework name of the ContextFileEnt. 6915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *ContextName = ContextFileEnt->getName(); 6921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the context info wasn't a framework, couldn't be a subframework. 694efda0e8705e79a4b7de9f18b0d4618515f9e4bccDouglas Gregor const unsigned DotFrameworkLen = 10; 695efda0e8705e79a4b7de9f18b0d4618515f9e4bccDouglas Gregor const char *FrameworkPos = strstr(ContextName, ".framework"); 696efda0e8705e79a4b7de9f18b0d4618515f9e4bccDouglas Gregor if (FrameworkPos == 0 || 697efda0e8705e79a4b7de9f18b0d4618515f9e4bccDouglas Gregor (FrameworkPos[DotFrameworkLen] != '/' && 698efda0e8705e79a4b7de9f18b0d4618515f9e4bccDouglas Gregor FrameworkPos[DotFrameworkLen] != '\\')) 6995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return 0; 7001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7019ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar SmallString<1024> FrameworkName(ContextName, FrameworkPos+DotFrameworkLen+1); 7025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 7035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Append Frameworks/HIToolbox.framework/ 7045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName += "Frameworks/"; 705a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos); 7065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName += ".framework/"; 7075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 7089ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar llvm::StringMapEntry<FrameworkCacheEntry> &CacheLookup = 7096538227d51df249b07c8ab80ae376f5c1d14403cChris Lattner FrameworkMap.GetOrCreateValue(Filename.substr(0, SlashPos)); 7101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Some other location? 7129ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar if (CacheLookup.getValue().Directory && 7135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer CacheLookup.getKeyLength() == FrameworkName.size() && 7145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer memcmp(CacheLookup.getKeyData(), &FrameworkName[0], 7155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer CacheLookup.getKeyLength()) != 0) 7165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return 0; 7171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Cache subframework. 7199ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar if (CacheLookup.getValue().Directory == 0) { 7205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ++NumSubFrameworkLookups; 7211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the framework dir doesn't exist, we fail. 72339b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str()); 7245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (Dir == 0) return 0; 7251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, if it does, remember that this is the right direntry for this 7275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // framework. 7289ee35f9f35452dec05c81fd1bbdd2f700872ea7fDaniel Dunbar CacheLookup.getValue().Directory = Dir; 7295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 7301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const FileEntry *FE = 0; 7325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 7337412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (RelativePath != NULL) { 7347412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 7357412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); 7367412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 7377412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 7385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h" 739f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<1024> HeadersFilename(FrameworkName); 7405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HeadersFilename += "Headers/"; 7417412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) { 7427412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 7437412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek // Without trailing '/'. 7447412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); 7457412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 7467412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 747a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 7483cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) { 7491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h" 7515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HeadersFilename = FrameworkName; 7525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HeadersFilename += "PrivateHeaders/"; 7537412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) { 7547412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 7557412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek // Without trailing '/'. 7567412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); 7577412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 7587412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 759a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 7603cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) 7615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return 0; 7625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 7631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // This file is a system header or C++ unfriendly if the old file is. 765ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek // 766c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner // Note that the temporary 'DirInfo' is required here, as either call to 767c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner // getFileInfo could resize the vector and we don't want to rely on order 768c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner // of evaluation. 769c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo; 770c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner getFileInfo(FE).DirInfo = DirInfo; 7711b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor 7721b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor // If we're supposed to suggest a module, look for one now. 7731b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor if (SuggestedModule) { 7741b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor // Find the top-level framework based on this framework. 7751b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor FrameworkName.pop_back(); // remove the trailing '/' 7761b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor SmallVector<std::string, 4> SubmodulePath; 7771b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor const DirectoryEntry *TopFrameworkDir 7781b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor = ::getTopFrameworkDir(FileMgr, FrameworkName, SubmodulePath); 7791b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor 7801b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor // Determine the name of the top-level framework. 7811b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName()); 7821b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor 7831b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor // Load this framework module. If that succeeds, find the suggested module 7841b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor // for this header, if any. 7851b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor bool IsSystem = false; 7861b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor if (loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystem)) { 7871b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor *SuggestedModule = findModuleForHeader(FE); 7881b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor } 7891b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor } 7901b58c74af272a1d8228b8161c93a8a018456098eDouglas Gregor 7915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return FE; 7925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 7935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 794cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth/// \brief Helper static function to normalize a path for injection into 795cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth/// a synthetic header. 796cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth/*static*/ std::string 797cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler CarruthHeaderSearch::NormalizeDashIncludePath(StringRef File, FileManager &FileMgr) { 798cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // Implicit include paths should be resolved relative to the current 799cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // working directory first, and then use the regular header search 800cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // mechanism. The proper way to handle this is to have the 801cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // predefines buffer located at the current working directory, but 802cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // it has no file entry. For now, workaround this by using an 803cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // absolute path if we find the file here, and otherwise letting 804cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth // header search handle it. 805f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> Path(File); 806cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth llvm::sys::fs::make_absolute(Path); 807cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth bool exists; 808cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth if (llvm::sys::fs::exists(Path.str(), exists) || !exists) 809cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth Path = File; 810cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth else if (exists) 811cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth FileMgr.getFile(File); 812cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth 813cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth return Lexer::Stringify(Path.str()); 814cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth} 815cb381eac84e5a14a8c7e7654eadbe1d3d54d795cChandler Carruth 8165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 8175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// File Info Management. 8185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 8195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 8208f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor/// \brief Merge the header file info provided by \p OtherHFI into the current 8218f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor/// header file info (\p HFI) 8228f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregorstatic void mergeHeaderFileInfo(HeaderFileInfo &HFI, 8238f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor const HeaderFileInfo &OtherHFI) { 8248f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.isImport |= OtherHFI.isImport; 8258f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.isPragmaOnce |= OtherHFI.isPragmaOnce; 82655ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis HFI.isModuleHeader |= OtherHFI.isModuleHeader; 8278f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.NumIncludes += OtherHFI.NumIncludes; 8288f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor 8298f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (!HFI.ControllingMacro && !HFI.ControllingMacroID) { 8308f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.ControllingMacro = OtherHFI.ControllingMacro; 8318f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.ControllingMacroID = OtherHFI.ControllingMacroID; 8328f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor } 8338f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor 8348f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (OtherHFI.External) { 8358f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.DirInfo = OtherHFI.DirInfo; 8368f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.External = OtherHFI.External; 8378f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.IndexHeaderMapHeader = OtherHFI.IndexHeaderMapHeader; 8388f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor } 8395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 8408f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (HFI.Framework.empty()) 8418f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.Framework = OtherHFI.Framework; 8428f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor 8438f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.Resolved = true; 8448f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor} 8458f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor 84683d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff/// getFileInfo - Return the HeaderFileInfo structure for the specified 8475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// FileEntry. 84883d63c78810556d26b62ac4cbae2eda6cdd2570cSteve NaroffHeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) { 8495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FE->getUID() >= FileInfo.size()) 8505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FileInfo.resize(FE->getUID()+1); 851cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 852cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor HeaderFileInfo &HFI = FileInfo[FE->getUID()]; 8538f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (ExternalSource && !HFI.Resolved) 8548f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(FE)); 855cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor return HFI; 8561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 8575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 858dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregorbool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) { 859dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor // Check if we've ever seen this file as a header. 860dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor if (File->getUID() >= FileInfo.size()) 861dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor return false; 862dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor 863dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor // Resolve header file info from the external source, if needed. 864dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor HeaderFileInfo &HFI = FileInfo[File->getUID()]; 8658f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (ExternalSource && !HFI.Resolved) 8668f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(File)); 867dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor 86844dfff681fdca5325bc684c46971efad1f3fedfdArgyrios Kyrtzidis return HFI.isPragmaOnce || HFI.isImport || 86944dfff681fdca5325bc684c46971efad1f3fedfdArgyrios Kyrtzidis HFI.ControllingMacro || HFI.ControllingMacroID; 870dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor} 871dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor 872d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidisvoid HeaderSearch::MarkFileModuleHeader(const FileEntry *FE, 873bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl ModuleMap::ModuleHeaderRole Role, 874d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis bool isCompilingModuleHeader) { 87555ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis if (FE->getUID() >= FileInfo.size()) 87655ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis FileInfo.resize(FE->getUID()+1); 87755ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis 87855ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis HeaderFileInfo &HFI = FileInfo[FE->getUID()]; 87955ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis HFI.isModuleHeader = true; 880d3220dbeeadc4ac54ceecea8cf63f8d8be291d2aArgyrios Kyrtzidis HFI.isCompilingModuleHeader = isCompilingModuleHeader; 881bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl HFI.setHeaderRole(Role); 88255ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis} 88355ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis 8845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){ 8855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ++NumIncluded; // Count # of attempted #includes. 8865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 8875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Get information about this file. 88883d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff HeaderFileInfo &FileInfo = getFileInfo(File); 8891eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this is a #import directive, check that we have not already imported 8915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // this header. 8925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (isImport) { 8935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this has already been imported, don't import it again. 8945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FileInfo.isImport = true; 8951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 8965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Has this already been #import'ed or #include'd? 8975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FileInfo.NumIncludes) return false; 8985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 8995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, if this is a #include of a file that was previously #import'd 9005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // or if this is the second #include of a #pragma once file, ignore it. 9015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FileInfo.isImport) 9025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return false; 9035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 9041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Next, check to see if the file is wrapped with #ifndef guards. If so, and 9065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // if the macro that guards it is defined, we know the #include has no effect. 9071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (const IdentifierInfo *ControllingMacro 9088c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor = FileInfo.getControllingMacro(ExternalLookup)) 9098c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor if (ControllingMacro->hasMacroDefinition()) { 9108c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor ++NumMultiIncludeFileOptzn; 9118c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor return false; 9128c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor } 9131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Increment the number of times this file has been included. 9155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ++FileInfo.NumIncludes; 9161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 9185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 9195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 920d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremeneksize_t HeaderSearch::getTotalMemory() const { 921d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek return SearchDirs.capacity() 922eabea45e23abc07e917f0d4bce15054ce75623efTed Kremenek + llvm::capacity_in_bytes(FileInfo) 923eabea45e23abc07e917f0d4bce15054ce75623efTed Kremenek + llvm::capacity_in_bytes(HeaderMaps) 924d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek + LookupFileCache.getAllocator().getTotalMemory() 925d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek + FrameworkMap.getAllocator().getTotalMemory(); 926d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek} 92765e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor 92865e02fa80e1c185f18e5f81cefc30d75383a7301Douglas GregorStringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) { 92965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor return FrameworkNames.GetOrCreateValue(Framework).getKey(); 93065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor} 931a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 932a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorbool HeaderSearch::hasModuleMap(StringRef FileName, 9338f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor const DirectoryEntry *Root, 9348f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor bool IsSystem) { 935cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<const DirectoryEntry *, 2> FixUpDirectories; 936a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 937a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringRef DirName = FileName; 938a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor do { 939a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Get the parent directory name. 940a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor DirName = llvm::sys::path::parent_path(DirName); 941a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (DirName.empty()) 942a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return false; 943a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 944a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Determine whether this directory exists. 945a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor const DirectoryEntry *Dir = FileMgr.getDirectory(DirName); 946a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Dir) 947a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return false; 948a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 949cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // Try to load the module map file in this directory. 9508f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor switch (loadModuleMapFile(Dir, IsSystem)) { 95126697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor case LMM_NewlyLoaded: 95226697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor case LMM_AlreadyLoaded: 953cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // Success. All of the directories we stepped through inherit this module 954cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // map file. 955a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I) 956a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor DirectoryHasModuleMap[FixUpDirectories[I]] = true; 957a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 958a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return true; 95926697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor 96026697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor case LMM_NoDirectory: 96126697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor case LMM_InvalidModuleMap: 96226697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor break; 963a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 964a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 965cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // If we hit the top of our search, we're done. 966cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (Dir == Root) 967cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor return false; 968cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 969a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Keep track of all of the directories we checked, so we can mark them as 970a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // having module maps if we eventually do find a module map. 971a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor FixUpDirectories.push_back(Dir); 972a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } while (true); 973a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 974a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 975bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence CrowlModuleMap::KnownHeader 976bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence CrowlHeaderSearch::findModuleForHeader(const FileEntry *File) const { 97755ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis if (ExternalSource) { 97855ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis // Make sure the external source has handled header info about this file, 97955ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis // which includes whether the file is part of a module. 98055ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis (void)getFileInfo(File); 98155ea75bf61a5d76f6453513d937944ce68181c6aArgyrios Kyrtzidis } 982bc3f628815b3841dc99109e7f67f9afa7793bc94Lawrence Crowl return ModMap.findModuleForHeader(File); 983a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 984a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 9858f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregorbool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem) { 986db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor const DirectoryEntry *Dir = File->getDir(); 987db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor 988db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir 989db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor = DirectoryHasModuleMap.find(Dir); 990db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor if (KnownDir != DirectoryHasModuleMap.end()) 991db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor return !KnownDir->second; 992db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor 9938f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor bool Result = ModMap.parseModuleMapFile(File, IsSystem); 9944813442c124d13a5c9cbf71beb7762275e45aacdDouglas Gregor if (!Result && llvm::sys::path::filename(File->getName()) == "module.map") { 9954813442c124d13a5c9cbf71beb7762275e45aacdDouglas Gregor // If the file we loaded was a module.map, look for the corresponding 9964813442c124d13a5c9cbf71beb7762275e45aacdDouglas Gregor // module_private.map. 997f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> PrivateFilename(Dir->getName()); 9984813442c124d13a5c9cbf71beb7762275e45aacdDouglas Gregor llvm::sys::path::append(PrivateFilename, "module_private.map"); 9994813442c124d13a5c9cbf71beb7762275e45aacdDouglas Gregor if (const FileEntry *PrivateFile = FileMgr.getFile(PrivateFilename)) 10008f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor Result = ModMap.parseModuleMapFile(PrivateFile, IsSystem); 10014813442c124d13a5c9cbf71beb7762275e45aacdDouglas Gregor } 10024813442c124d13a5c9cbf71beb7762275e45aacdDouglas Gregor 10034813442c124d13a5c9cbf71beb7762275e45aacdDouglas Gregor DirectoryHasModuleMap[Dir] = !Result; 1004db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor return Result; 1005db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor} 1006db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor 1007e434ec71fccfe078906403affd641f709702d598Douglas GregorModule *HeaderSearch::loadFrameworkModule(StringRef Name, 1008e434ec71fccfe078906403affd641f709702d598Douglas Gregor const DirectoryEntry *Dir, 1009e434ec71fccfe078906403affd641f709702d598Douglas Gregor bool IsSystem) { 10101a4761edca58c6b559de825b9abfb66f7f1ba94aDouglas Gregor if (Module *Module = ModMap.findModule(Name)) 10112821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor return Module; 10122821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 10132821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor // Try to load a module map file. 10148f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor switch (loadModuleMapFile(Dir, IsSystem)) { 10152821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor case LMM_InvalidModuleMap: 10162821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor break; 10172821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 10182821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor case LMM_AlreadyLoaded: 10192821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor case LMM_NoDirectory: 10202821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor return 0; 10212821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 10222821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor case LMM_NewlyLoaded: 10232821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor return ModMap.findModule(Name); 10242821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor } 1025a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor 10267005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // Figure out the top-level framework directory and the submodule path from 10277005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor // that top-level framework to the requested framework. 1028cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<std::string, 2> SubmodulePath; 1029a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor SubmodulePath.push_back(Name); 10307005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor const DirectoryEntry *TopFrameworkDir 10317005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor = ::getTopFrameworkDir(FileMgr, Dir->getName(), SubmodulePath); 103282e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 103382e52377bd76ed71e8c09edc5f2f452e388b16adDouglas Gregor 1034a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor // Try to infer a module map from the top-level framework directory. 1035a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor Module *Result = ModMap.inferFrameworkModule(SubmodulePath.back(), 1036a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor TopFrameworkDir, 1037a1f1fad8b60e1cb9d21a40a37f2e03150bcbeb6fDouglas Gregor IsSystem, 1038a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor /*Parent=*/0); 10397005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor if (!Result) 10407005b907ea159c8e74e81f85269777429bc18d3cDouglas Gregor return 0; 1041a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor 1042a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor // Follow the submodule path to find the requested (sub)framework module 1043a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor // within the top-level framework module. 1044a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor SubmodulePath.pop_back(); 1045a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor while (!SubmodulePath.empty() && Result) { 1046a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor Result = ModMap.lookupModuleQualified(SubmodulePath.back(), Result); 1047a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor SubmodulePath.pop_back(); 1048a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor } 1049a8c6fea0234bc23de6106a84646dc049cf45e8c8Douglas Gregor return Result; 10502821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor} 10512821c7f8870629b56b9c41e1c50c7a091edd544dDouglas Gregor 1052db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor 105326697979fb0a4e2b720a0c8d062047edca92bc92Douglas GregorHeaderSearch::LoadModuleMapResult 10548f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas GregorHeaderSearch::loadModuleMapFile(StringRef DirName, bool IsSystem) { 1055cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (const DirectoryEntry *Dir = FileMgr.getDirectory(DirName)) 10568f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor return loadModuleMapFile(Dir, IsSystem); 1057cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 105826697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor return LMM_NoDirectory; 1059cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor} 1060cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 106126697979fb0a4e2b720a0c8d062047edca92bc92Douglas GregorHeaderSearch::LoadModuleMapResult 10628f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas GregorHeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir, bool IsSystem) { 1063cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir 1064cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor = DirectoryHasModuleMap.find(Dir); 1065cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (KnownDir != DirectoryHasModuleMap.end()) 106626697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor return KnownDir->second? LMM_AlreadyLoaded : LMM_InvalidModuleMap; 1067cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 1068f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> ModuleMapFileName; 1069cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor ModuleMapFileName += Dir->getName(); 1070587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor unsigned ModuleMapDirNameLen = ModuleMapFileName.size(); 1071cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor llvm::sys::path::append(ModuleMapFileName, "module.map"); 1072cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (const FileEntry *ModuleMapFile = FileMgr.getFile(ModuleMapFileName)) { 1073cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // We have found a module map file. Try to parse it. 10748f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor if (ModMap.parseModuleMapFile(ModuleMapFile, IsSystem)) { 1075587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // No suitable module map. 1076587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor DirectoryHasModuleMap[Dir] = false; 1077587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return LMM_InvalidModuleMap; 1078cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 1079587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1080587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // This directory has a module map. 1081587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor DirectoryHasModuleMap[Dir] = true; 1082587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1083587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // Check whether there is a private module map that we need to load as well. 1084587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ModuleMapFileName.erase(ModuleMapFileName.begin() + ModuleMapDirNameLen, 1085587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor ModuleMapFileName.end()); 1086587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor llvm::sys::path::append(ModuleMapFileName, "module_private.map"); 1087587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor if (const FileEntry *PrivateModuleMapFile 1088587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor = FileMgr.getFile(ModuleMapFileName)) { 10898f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor if (ModMap.parseModuleMapFile(PrivateModuleMapFile, IsSystem)) { 1090587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor // No suitable module map. 1091587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor DirectoryHasModuleMap[Dir] = false; 1092587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return LMM_InvalidModuleMap; 1093587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1094587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor } 1095587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor 1096587986efc5ca409da3ebf0a4ab7f72ebf50a3ab9Douglas Gregor return LMM_NewlyLoaded; 1097cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 1098cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 1099cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // No suitable module map. 1100cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor DirectoryHasModuleMap[Dir] = false; 110126697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor return LMM_InvalidModuleMap; 1102cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor} 1103a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 1104cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenkovoid HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) { 1105c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor Modules.clear(); 1106c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1107c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // Load module maps for each of the header search directories. 1108c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { 11098f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory(); 1110c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor if (SearchDirs[Idx].isFramework()) { 1111c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor llvm::error_code EC; 1112f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<128> DirNative; 1113c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(), 1114c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor DirNative); 1115c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1116c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // Search each of the ".framework" directories to load them as modules. 1117c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; 1118c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor Dir != DirEnd && !EC; Dir.increment(EC)) { 1119c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor if (llvm::sys::path::extension(Dir->path()) != ".framework") 1120c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor continue; 1121c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1122c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor const DirectoryEntry *FrameworkDir = FileMgr.getDirectory(Dir->path()); 1123c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor if (!FrameworkDir) 1124c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor continue; 1125c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1126c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // Load this framework module. 1127c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor loadFrameworkModule(llvm::sys::path::stem(Dir->path()), FrameworkDir, 1128c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor IsSystem); 1129c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor } 1130c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor continue; 1131c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor } 1132c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1133c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // FIXME: Deal with header maps. 1134c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor if (SearchDirs[Idx].isHeaderMap()) 1135c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor continue; 1136c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1137c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // Try to load a module map file for the search directory. 11388f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem); 1139c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1140c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // Try to load module map files for immediate subdirectories of this search 1141c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // directory. 1142cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor loadSubdirectoryModuleMaps(SearchDirs[Idx]); 1143c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor } 1144c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor 1145c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor // Populate the list of modules. 1146c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor for (ModuleMap::module_iterator M = ModMap.module_begin(), 1147c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor MEnd = ModMap.module_end(); 1148c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor M != MEnd; ++M) { 1149c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor Modules.push_back(M->getValue()); 1150c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor } 1151c5b2e58840748145d1706c1d1481369d1863fabfDouglas Gregor} 1152cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor 115330a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregorvoid HeaderSearch::loadTopLevelSystemModules() { 115430a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor // Load module maps for each of the header search directories. 115530a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { 115630a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor // We only care about normal system header directories. 115730a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor if (!SearchDirs[Idx].isNormalDir() || 115830a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_System) { 115930a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor continue; 116030a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor } 116130a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor 116230a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor // Try to load a module map file for the search directory. 11638f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor loadModuleMapFile(SearchDirs[Idx].getDir(), 11648f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor SearchDirs[Idx].isSystemHeaderDirectory()); 116530a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor } 116630a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor} 116730a16f1383b56cb71be251999a577b2e37db2ce0Douglas Gregor 1168cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregorvoid HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) { 1169cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor if (SearchDir.haveSearchedAllModuleMaps()) 1170cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor return; 1171cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor 1172cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor llvm::error_code EC; 1173cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor SmallString<128> DirNative; 1174cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor llvm::sys::path::native(SearchDir.getDir()->getName(), DirNative); 1175cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; 1176cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor Dir != DirEnd && !EC; Dir.increment(EC)) { 11778f5d7d1d1f990f174c7f2682271a83acf64dd93dDouglas Gregor loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory()); 1178cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor } 1179cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor 1180cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor SearchDir.setSearchedAllModuleMaps(true); 1181cdf2808c4e735a717599751dcd2b434f239e1c68Douglas Gregor} 1182