HeaderSearch.cpp revision db1cde7dc7bb3aaf48118bd9605192ab94a93635
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- HeaderSearch.cpp - Resolve Header File Locations ---===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file implements the DirectoryLookup and HeaderSearch interfaces. 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Lex/HeaderSearch.h" 15822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner#include "clang/Lex/HeaderMap.h" 16a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor#include "clang/Basic/Diagnostic.h" 17c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#include "clang/Basic/FileManager.h" 18c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#include "clang/Basic/IdentifierTable.h" 1932bef4edba854303800b3b01cb49a282e5da4f69Michael J. Spencer#include "llvm/Support/FileSystem.h" 2003013fa9a0bf1ef4b907f5fec006c8f4000fdd21Michael J. Spencer#include "llvm/Support/Path.h" 215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "llvm/ADT/SmallString.h" 22eabea45e23abc07e917f0d4bce15054ce75623efTed Kremenek#include "llvm/Support/Capacity.h" 233daed52a57d03765223021f5f921bdc280c8f3ccChris Lattner#include <cstdio> 245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 268c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregorconst IdentifierInfo * 278c5a760b82e73ed90b560090772db97e2ae27b09Douglas GregorHeaderFileInfo::getControllingMacro(ExternalIdentifierLookup *External) { 288c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor if (ControllingMacro) 298c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor return ControllingMacro; 308c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 318c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor if (!ControllingMacroID || !External) 328c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor return 0; 338c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 348c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor ControllingMacro = External->GetIdentifier(ControllingMacroID); 358c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor return ControllingMacro; 368c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor} 378c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 38cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas GregorExternalHeaderFileInfoSource::~ExternalHeaderFileInfoSource() {} 39cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 408e23806863721495f9e1f84aed614f7afba774a3Douglas GregorHeaderSearch::HeaderSearch(FileManager &FM, DiagnosticsEngine &Diags) 41a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor : FileMgr(FM), Diags(Diags), FrameworkMap(64), 42a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor ModMap(FileMgr, *Diags.getClient()) 438e23806863721495f9e1f84aed614f7afba774a3Douglas Gregor{ 4474a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber AngledDirIdx = 0; 455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SystemDirIdx = 0; 465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NoCurDirSearch = false; 471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 488c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor ExternalLookup = 0; 49cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor ExternalSource = 0; 505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumIncluded = 0; 515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumMultiIncludeFileOptzn = 0; 525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumFrameworkLookups = NumSubFrameworkLookups = 0; 535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 55822da61b74ce14e89b3fa8774db18c833aa5748bChris LattnerHeaderSearch::~HeaderSearch() { 56822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner // Delete headermaps. 57822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i) 58822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner delete HeaderMaps[i].second; 59822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner} 601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid HeaderSearch::PrintStats() { 625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "\n*** HeaderSearch Stats:\n"); 635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "%d files tracked.\n", (int)FileInfo.size()); 645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0; 655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer for (unsigned i = 0, e = FileInfo.size(); i != e; ++i) { 665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumOnceOnlyFiles += FileInfo[i].isImport; 675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (MaxNumIncludes < FileInfo[i].NumIncludes) 685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer MaxNumIncludes = FileInfo[i].NumIncludes; 695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1; 705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d #import/#pragma once files.\n", NumOnceOnlyFiles); 725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d included exactly once.\n", NumSingleIncludedFiles); 735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d max times a file is included.\n", MaxNumIncludes); 741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d #include/#include_next/#import.\n", NumIncluded); 765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, " %d #includes skipped due to" 775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer " the multi-include optimization.\n", NumMultiIncludeFileOptzn); 781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "%d framework lookups.\n", NumFrameworkLookups); 805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "%d subframework lookups.\n", NumSubFrameworkLookups); 815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 83822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner/// CreateHeaderMap - This method returns a HeaderMap for the specified 84822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner/// FileEntry, uniquing them through the the 'HeaderMaps' datastructure. 851bfd4a6313ea8ebf710c46c10111732cc65d51f6Chris Lattnerconst HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) { 86822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner // We expect the number of headermaps to be small, and almost always empty. 87df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner // If it ever grows, use of a linear search should be re-evaluated. 88822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner if (!HeaderMaps.empty()) { 89822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i) 90df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner // Pointer equality comparison of FileEntries works because they are 91df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner // already uniqued by inode. 921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (HeaderMaps[i].first == FE) 93822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner return HeaderMaps[i].second; 94822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner } 951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 9639b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner if (const HeaderMap *HM = HeaderMap::Create(FE, FileMgr)) { 97822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner HeaderMaps.push_back(std::make_pair(FE, HM)); 98822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner return HM; 99822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner } 1001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 101822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner return 0; 102822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner} 103822da61b74ce14e89b3fa8774db18c833aa5748bChris Lattner 10421cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregorconst FileEntry *HeaderSearch::lookupModule(StringRef ModuleName, 1056e975c4517958bcc11c834336d340797356058dbDouglas Gregor std::string *ModuleFileName, 10621cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor std::string *UmbrellaHeader) { 1079a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor // If we don't have a module cache path, we can't do anything. 1086e975c4517958bcc11c834336d340797356058dbDouglas Gregor if (ModuleCachePath.empty()) { 1096e975c4517958bcc11c834336d340797356058dbDouglas Gregor if (ModuleFileName) 1106e975c4517958bcc11c834336d340797356058dbDouglas Gregor ModuleFileName->clear(); 1119a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor return 0; 1126e975c4517958bcc11c834336d340797356058dbDouglas Gregor } 1136e975c4517958bcc11c834336d340797356058dbDouglas Gregor 11421cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor // Try to find the module path. 1159a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor llvm::SmallString<256> FileName(ModuleCachePath); 1169a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor llvm::sys::path::append(FileName, ModuleName + ".pcm"); 1176e975c4517958bcc11c834336d340797356058dbDouglas Gregor if (ModuleFileName) 1186e975c4517958bcc11c834336d340797356058dbDouglas Gregor *ModuleFileName = FileName.str(); 1196e975c4517958bcc11c834336d340797356058dbDouglas Gregor 1206e975c4517958bcc11c834336d340797356058dbDouglas Gregor if (const FileEntry *ModuleFile 1216e975c4517958bcc11c834336d340797356058dbDouglas Gregor = getFileMgr().getFile(FileName, /*OpenFile=*/false, 1226e975c4517958bcc11c834336d340797356058dbDouglas Gregor /*CacheFailure=*/false)) 12321cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor return ModuleFile; 12421cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor 12521cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor // We didn't find the module. If we're not supposed to look for an 12621cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor // umbrella header, this is the end of the road. 12721cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor if (!UmbrellaHeader) 12821cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor return 0; 12921cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor 130cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // Look in the module map to determine if there is a module by this name. 131cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor ModuleMap::Module *Module = ModMap.findModule(ModuleName); 132cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (!Module) { 133cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // Look through the various header search paths to load any avaiable module 134cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // maps, searching for a module map that describes this module. 135cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { 136cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // Skip non-normal include paths 137cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (!SearchDirs[Idx].isNormalDir()) 138cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor continue; 139cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 14026697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor // Search for a module map file in this directory. 14126697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor if (loadModuleMapFile(SearchDirs[Idx].getDir()) == LMM_NewlyLoaded) { 14226697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor // We just loaded a module map file; check whether the module is 14326697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor // available now. 144cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor Module = ModMap.findModule(ModuleName); 145cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (Module) 146cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor break; 147cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 14826697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor 149cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // Search for a module map in a subdirectory with the same name as the 150cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // module. 151cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor llvm::SmallString<128> NestedModuleMapDirName; 152cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName(); 153cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor llvm::sys::path::append(NestedModuleMapDirName, ModuleName); 15426697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor if (loadModuleMapFile(NestedModuleMapDirName) == LMM_NewlyLoaded) { 15526697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor // If we just loaded a module map file, look for the module again. 156cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor Module = ModMap.findModule(ModuleName); 157cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (Module) 158cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor break; 159cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 160cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 161cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 162cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 163cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // If we have a module with an umbrella header 164484535e45b4d301847a157e943c7823da5d40884Douglas Gregor // FIXME: Even if it doesn't have an umbrella header, we should be able to 165484535e45b4d301847a157e943c7823da5d40884Douglas Gregor // handle the module. However, the caller isn't ready for that yet. 166cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (Module && Module->UmbrellaHeader) { 167cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor *UmbrellaHeader = Module->UmbrellaHeader->getName(); 168cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor return 0; 169484535e45b4d301847a157e943c7823da5d40884Douglas Gregor } 170484535e45b4d301847a157e943c7823da5d40884Douglas Gregor 17121cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor // Look in each of the framework directories for an umbrella header with 17221cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor // the same name as the module. 17321cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor llvm::SmallString<128> UmbrellaHeaderName; 17421cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor UmbrellaHeaderName = ModuleName; 17521cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor UmbrellaHeaderName += '/'; 17621cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor UmbrellaHeaderName += ModuleName; 17721cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor UmbrellaHeaderName += ".h"; 17821cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { 17921cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor // Skip non-framework include paths 18021cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor if (!SearchDirs[Idx].isFramework()) 18121cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor continue; 18221cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor 18321cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor // Look for the umbrella header in this directory. 18421cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor if (const FileEntry *HeaderFile 185fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor = SearchDirs[Idx].LookupFile(UmbrellaHeaderName, *this, 0, 0, 186fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor StringRef(), 0)) { 18721cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor *UmbrellaHeader = HeaderFile->getName(); 18821cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor return 0; 18921cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor } 19021cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor } 19121cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor 19221cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor // We did not find an umbrella header. Clear out the UmbrellaHeader pointee 19321cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor // so our caller knows that we failed. 19421cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor UmbrellaHeader->clear(); 19521cae2059a06f7d89eee169409c9266def1b1acaDouglas Gregor return 0; 1969a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor} 1979a6da6930644b4f2dbe4885b0eb4fc1274ff56a4Douglas Gregor 198df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner//===----------------------------------------------------------------------===// 199df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner// File lookup within a DirectoryLookup scope 200df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner//===----------------------------------------------------------------------===// 201df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner 2023af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner/// getName - Return the directory or filename corresponding to this lookup 2033af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner/// object. 2043af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattnerconst char *DirectoryLookup::getName() const { 2053af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner if (isNormalDir()) 2063af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner return getDir()->getName(); 2073af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner if (isFramework()) 2083af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner return getFrameworkDir()->getName(); 2093af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner assert(isHeaderMap() && "Unknown DirectoryLookup"); 2103af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner return getHeaderMap()->getFileName(); 2113af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner} 2123af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner 2133af66a9335966e9114e660cf7aafbb9272190ec2Chris Lattner 214df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner/// LookupFile - Lookup the specified file in this search path, returning it 215df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner/// if it exists or returning null if not. 216b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruthconst FileEntry *DirectoryLookup::LookupFile( 2175f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Filename, 2187412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek HeaderSearch &HS, 2195f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> *SearchPath, 220fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SmallVectorImpl<char> *RelativePath, 221fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor StringRef BuildingModule, 222fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor StringRef *SuggestedModule) const { 223df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner llvm::SmallString<1024> TmpDir; 224afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner if (isNormalDir()) { 225afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // Concatenate the requested file onto the directory. 226a6e023c4491a8a8116c11783f4e81c7bd172f88dEli Friedman TmpDir = getDir()->getName(); 227a6e023c4491a8a8116c11783f4e81c7bd172f88dEli Friedman llvm::sys::path::append(TmpDir, Filename); 2287412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) { 2295f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef SearchPathRef(getDir()->getName()); 2307412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 2317412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 2327412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 2337412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (RelativePath != NULL) { 2347412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 2357412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin(), Filename.end()); 2367412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 237a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 238a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // If we have a module map that might map this header, load it and 239a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // check whether we'll have a suggestion for a module. 240a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (SuggestedModule && HS.hasModuleMap(TmpDir, getDir())) { 241a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor const FileEntry *File = HS.getFileMgr().getFile(TmpDir.str(), 242a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor /*openFile=*/false); 243a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!File) 244a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return File; 245a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 246a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // If there is a module that corresponds to this header, 247a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // suggest it. 24865f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor StringRef Module = HS.findModuleForHeader(File); 249a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Module.empty() && Module != BuildingModule) 250a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor *SuggestedModule = Module; 251a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 252a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return File; 253a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 254a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 2553cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis return HS.getFileMgr().getFile(TmpDir.str(), /*openFile=*/true); 256afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner } 2571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 258afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner if (isFramework()) 259fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath, 260fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor BuildingModule, SuggestedModule); 2611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 262b09e71fd52d0e7fdf3e88b1df72ea0cee5d9b37bChris Lattner assert(isHeaderMap() && "Unknown directory lookup"); 2637412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek const FileEntry * const Result = getHeaderMap()->LookupFile( 2647412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek Filename, HS.getFileMgr()); 2657412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (Result) { 2667412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) { 2675f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef SearchPathRef(getName()); 2687412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 2697412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 2707412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 2717412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (RelativePath != NULL) { 2727412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 2737412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin(), Filename.end()); 2747412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 2757412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 2767412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek return Result; 277df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner} 278df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner 279df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner 280afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner/// DoFrameworkLookup - Do a lookup of the specified file in the current 281afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner/// DirectoryLookup, which is a framework directory. 282b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruthconst FileEntry *DirectoryLookup::DoFrameworkLookup( 2835f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Filename, 2847412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek HeaderSearch &HS, 2855f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> *SearchPath, 286fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SmallVectorImpl<char> *RelativePath, 287fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor StringRef BuildingModule, 288fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor StringRef *SuggestedModule) const 289fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor{ 290afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner FileManager &FileMgr = HS.getFileMgr(); 2911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Framework names must have a '/' in the filename. 293a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner size_t SlashPos = Filename.find('/'); 2945f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner if (SlashPos == StringRef::npos) return 0; 2951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 296afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // Find out if this is the home for the specified framework, by checking 297afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // HeaderSearch. Possible answer are yes/no and unknown. 2981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const DirectoryEntry *&FrameworkDirCache = 299a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner HS.LookupFrameworkCache(Filename.substr(0, SlashPos)); 3001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 301afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // If it is known and in some other directory, fail. 302afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner if (FrameworkDirCache && FrameworkDirCache != getFrameworkDir()) 3035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return 0; 3041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 305afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // Otherwise, construct the path to this framework dir. 3061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // FrameworkName = "/System/Library/Frameworks/" 3085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::SmallString<1024> FrameworkName; 309afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner FrameworkName += getFrameworkDir()->getName(); 3105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FrameworkName.empty() || FrameworkName.back() != '/') 3115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName.push_back('/'); 3121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // FrameworkName = "/System/Library/Frameworks/Cocoa" 314a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos); 3151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/" 3175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName += ".framework/"; 3181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 319afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // If the cache entry is still unresolved, query to see if the cache entry is 320afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // still unresolved. If so, check its existence now. 321afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner if (FrameworkDirCache == 0) { 322afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner HS.IncrementFrameworkLookupCount(); 3231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the framework dir doesn't exist, we fail. 325afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // FIXME: It's probably more efficient to query this with FileMgr.getDir. 32632bef4edba854303800b3b01cb49a282e5da4f69Michael J. Spencer bool Exists; 32732bef4edba854303800b3b01cb49a282e5da4f69Michael J. Spencer if (llvm::sys::fs::exists(FrameworkName.str(), Exists) || !Exists) 3285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return 0; 3291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, if it does, remember that this is the right direntry for this 3315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // framework. 332afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner FrameworkDirCache = getFrameworkDir(); 3335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 3341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3357412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (RelativePath != NULL) { 3367412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 3377412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); 3387412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 3397412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 3405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h" 3415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned OrigSize = FrameworkName.size(); 3421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName += "Headers/"; 3447412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 3457412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) { 3467412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 3477412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek // Without trailing '/'. 3487412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1); 3497412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 3507412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 351fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor /// Determine whether this is the module we're building or not. 352fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor bool AutomaticImport = SuggestedModule && 3530fd787bb8529ace1cb7af592193ba22d0bab2d36Douglas Gregor (BuildingModule != StringRef(Filename.begin(), SlashPos)) && 3540fd787bb8529ace1cb7af592193ba22d0bab2d36Douglas Gregor !Filename.substr(SlashPos + 1).startswith(".."); 355fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor 356a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end()); 3573cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis if (const FileEntry *FE = FileMgr.getFile(FrameworkName.str(), 358fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor /*openFile=*/!AutomaticImport)) { 359fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor if (AutomaticImport) 360fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor *SuggestedModule = StringRef(Filename.begin(), SlashPos); 3615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return FE; 362b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth } 3631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h" 3655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *Private = "Private"; 3661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump FrameworkName.insert(FrameworkName.begin()+OrigSize, Private, 3675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Private+strlen(Private)); 3687412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) 3697412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->insert(SearchPath->begin()+OrigSize, Private, 3707412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek Private+strlen(Private)); 3717412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 372fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor const FileEntry *FE = FileMgr.getFile(FrameworkName.str(), 373fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor /*openFile=*/!AutomaticImport); 374fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor if (FE && AutomaticImport) 375fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor *SuggestedModule = StringRef(Filename.begin(), SlashPos); 376fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor return FE; 3775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 3785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 379df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner 380afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner//===----------------------------------------------------------------------===// 381afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner// Header File Location. 382afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner//===----------------------------------------------------------------------===// 383afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner 384afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner 3855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// LookupFile - Given a "foo" or <foo> reference, look up the indicated file, 3865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// return null on failure. isAngled indicates whether the file reference is 38710fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor/// for system #include's or not (i.e. using <> instead of ""). CurFileEnt, if 38810fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor/// non-null, indicates where the #including file is, in case a relative search 38910fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor/// is needed. 390b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruthconst FileEntry *HeaderSearch::LookupFile( 3915f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef Filename, 392b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth bool isAngled, 393b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth const DirectoryLookup *FromDir, 394b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth const DirectoryLookup *&CurDir, 395b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth const FileEntry *CurFileEnt, 3965f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> *SearchPath, 397fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SmallVectorImpl<char> *RelativePath, 398fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor StringRef *SuggestedModule) 399fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor{ 400fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor if (SuggestedModule) 401fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor *SuggestedModule = StringRef(); 402fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor 4035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If 'Filename' is absolute, check to see if it exists and no searching. 404256053b31e697fdf0cc48f17d621c82fc3b8dff0Michael J. Spencer if (llvm::sys::path::is_absolute(Filename)) { 4055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer CurDir = 0; 4065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this was an #include_next "/absolute/file", fail. 4085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FromDir) return 0; 4091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4107412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) 4117412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 4127412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (RelativePath != NULL) { 4137412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 4147412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin(), Filename.end()); 4157412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 4165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, just return the file. 4173cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis return FileMgr.getFile(Filename, /*openFile=*/true); 4185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 4191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 42065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor // Unless disabled, check to see if the file is in the #includer's 42110fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // directory. This has to be based on CurFileEnt, not CurDir, because 42210fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // CurFileEnt could be a #include of a subdirectory (#include "foo/bar.h") and 423df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner // a subsequent include of "baz.h" should resolve to "whatever/foo/baz.h". 424df772336655fd84ee2c0ce514c93cef0b29d60d4Chris Lattner // This search is not done for <> headers. 42510fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor if (CurFileEnt && !isAngled && !NoCurDirSearch) { 42610fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor llvm::SmallString<1024> TmpDir; 42710fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // Concatenate the requested file onto the directory. 42810fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // FIXME: Portability. Filename concatenation should be in sys::Path. 42910fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor TmpDir += CurFileEnt->getDir()->getName(); 43010fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor TmpDir.push_back('/'); 43110fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor TmpDir.append(Filename.begin(), Filename.end()); 4323cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis if (const FileEntry *FE = FileMgr.getFile(TmpDir.str(),/*openFile=*/true)) { 4335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Leave CurDir unset. 43410fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // This file is a system header or C++ unfriendly if the old file is. 43510fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // 43610fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // Note that the temporary 'DirInfo' is required here, as either call to 43710fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // getFileInfo could resize the vector and we don't want to rely on order 43810fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor // of evaluation. 43910fe93d57c11f068aa4d78eb4ca7f60329818306Douglas Gregor unsigned DirInfo = getFileInfo(CurFileEnt).DirInfo; 440c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner getFileInfo(FE).DirInfo = DirInfo; 4417412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) { 4425f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef SearchPathRef(CurFileEnt->getDir()->getName()); 4437412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 4447412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(SearchPathRef.begin(), SearchPathRef.end()); 4457412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 4467412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (RelativePath != NULL) { 4477412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 4487412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin(), Filename.end()); 4497412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 4505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return FE; 4515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 4525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 4531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer CurDir = 0; 4555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 4565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this is a system #include, ignore the user #include locs. 45774a5fd8bcc68b540b58f6fcd2d80e6e926966e71Nico Weber unsigned i = isAngled ? AngledDirIdx : 0; 4581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this is a #include_next request, start searching after the directory the 4605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // file was found in. 4615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FromDir) 4625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer i = FromDir-&SearchDirs[0]; 4631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4649960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // Cache all of the lookups performed by this method. Many headers are 4659960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // multiply included, and the "pragma once" optimization prevents them from 4669960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // being relex/pp'd, but they would still have to search through a 4679960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // (potentially huge) series of SearchDirs to find it. 4689960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner std::pair<unsigned, unsigned> &CacheLookup = 469a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner LookupFileCache.GetOrCreateValue(Filename).getValue(); 4709960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner 4719960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // If the entry has been previously looked up, the first value will be 4729960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // non-zero. If the value is equal to i (the start point of our search), then 4739960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // this is a matching hit. 4749960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner if (CacheLookup.first == i+1) { 4759960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // Skip querying potentially lots of directories for this lookup. 4769960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner i = CacheLookup.second; 4779960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner } else { 4789960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // Otherwise, this is the first query, or the previous query didn't match 4799960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // our search start. We will fill in our found location below, so prime the 4809960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // start point value. 4819960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner CacheLookup.first = i+1; 4829960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner } 4831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Check each directory in sequence to see if it contains this file. 4855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer for (; i != SearchDirs.size(); ++i) { 4861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const FileEntry *FE = 487fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath, 488fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor BuildingModule, SuggestedModule); 489afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner if (!FE) continue; 4901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 491afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner CurDir = &SearchDirs[i]; 4921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 493afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // This file is a system header or C++ unfriendly if the dir is. 49465e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor HeaderFileInfo &HFI = getFileInfo(FE); 49565e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor HFI.DirInfo = CurDir->getDirCharacteristic(); 49665e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor 49765e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor // If this file is found in a header map and uses the framework style of 49865e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor // includes, then this header is part of a framework we're building. 49965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor if (CurDir->isIndexHeaderMap()) { 50065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor size_t SlashPos = Filename.find('/'); 50165e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor if (SlashPos != StringRef::npos) { 50265e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor HFI.IndexHeaderMapHeader = 1; 50365e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor HFI.Framework = getUniqueFrameworkName(StringRef(Filename.begin(), 50465e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor SlashPos)); 50565e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor } 50665e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor } 50765e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor 508afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner // Remember this location for the next lookup we do. 509afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner CacheLookup.second = i; 510afded5bbb85607023c710c3d6a96c372feb84d7fChris Lattner return FE; 5115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 5121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5132c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor // If we are including a file with a quoted include "foo.h" from inside 5142c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor // a header in a framework that is currently being built, and we couldn't 5152c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor // resolve "foo.h" any other way, change the include to <Foo/foo.h>, where 5162c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor // "Foo" is the name of the framework in which the including header was found. 5172c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor if (CurFileEnt && !isAngled && Filename.find('/') == StringRef::npos) { 5182c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor HeaderFileInfo &IncludingHFI = getFileInfo(CurFileEnt); 5192c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor if (IncludingHFI.IndexHeaderMapHeader) { 5202c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor llvm::SmallString<128> ScratchFilename; 5212c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor ScratchFilename += IncludingHFI.Framework; 5222c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor ScratchFilename += '/'; 5232c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor ScratchFilename += Filename; 5242c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor 5252c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor const FileEntry *Result = LookupFile(ScratchFilename, /*isAngled=*/true, 5262c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor FromDir, CurDir, CurFileEnt, 527fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SearchPath, RelativePath, 528fba18aa8f2cd1994dc65e8cb9f4be201c560dc0bDouglas Gregor SuggestedModule); 5292c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor std::pair<unsigned, unsigned> &CacheLookup 5302c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor = LookupFileCache.GetOrCreateValue(Filename).getValue(); 5312c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor CacheLookup.second 5322c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor = LookupFileCache.GetOrCreateValue(ScratchFilename).getValue().second; 5332c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor return Result; 5342c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor } 5352c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor } 5362c7b7803182d1796225bf420d17b216bd81f75b0Douglas Gregor 5379960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner // Otherwise, didn't find it. Remember we didn't find this. 5389960ae8ecfa2c4278dac708a02e463f83fdf17e8Chris Lattner CacheLookup.second = SearchDirs.size(); 5395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return 0; 5405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 5415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// LookupSubframeworkHeader - Look up a subframework for the specified 5435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// #include file. For example, if #include'ing <HIToolbox/HIToolbox.h> from 5445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox 5455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// is a subframework within Carbon.framework. If so, return the FileEntry 5465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// for the designated file, otherwise return null. 5475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerconst FileEntry *HeaderSearch:: 5485f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerLookupSubframeworkHeader(StringRef Filename, 549b5142bb7af5c70fffd09f05172a1379a35a9c29aChandler Carruth const FileEntry *ContextFileEnt, 5505f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> *SearchPath, 5515f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVectorImpl<char> *RelativePath) { 5529415a0cc93117b69add4e1dc0f11146f3479ee1aChris Lattner assert(ContextFileEnt && "No context file?"); 5531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Framework names must have a '/' in the filename. Find it. 555a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner size_t SlashPos = Filename.find('/'); 5565f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner if (SlashPos == StringRef::npos) return 0; 5571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Look up the base framework name of the ContextFileEnt. 5595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *ContextName = ContextFileEnt->getName(); 5601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the context info wasn't a framework, couldn't be a subframework. 5625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const char *FrameworkPos = strstr(ContextName, ".framework/"); 5635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FrameworkPos == 0) 5645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return 0; 5651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump llvm::SmallString<1024> FrameworkName(ContextName, 5675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkPos+strlen(".framework/")); 5685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Append Frameworks/HIToolbox.framework/ 5705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName += "Frameworks/"; 571a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos); 5725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FrameworkName += ".framework/"; 5735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::StringMapEntry<const DirectoryEntry *> &CacheLookup = 5756538227d51df249b07c8ab80ae376f5c1d14403cChris Lattner FrameworkMap.GetOrCreateValue(Filename.substr(0, SlashPos)); 5761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Some other location? 5785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (CacheLookup.getValue() && 5795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer CacheLookup.getKeyLength() == FrameworkName.size() && 5805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer memcmp(CacheLookup.getKeyData(), &FrameworkName[0], 5815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer CacheLookup.getKeyLength()) != 0) 5825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return 0; 5831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Cache subframework. 5855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (CacheLookup.getValue() == 0) { 5865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ++NumSubFrameworkLookups; 5871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If the framework dir doesn't exist, we fail. 58939b49bcaaddb1049234fca9500c0ac02c088e23dChris Lattner const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str()); 5905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (Dir == 0) return 0; 5911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, if it does, remember that this is the right direntry for this 5935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // framework. 5945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer CacheLookup.setValue(Dir); 5955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 5961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const FileEntry *FE = 0; 5985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5997412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (RelativePath != NULL) { 6007412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->clear(); 6017412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek RelativePath->append(Filename.begin()+SlashPos+1, Filename.end()); 6027412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 6037412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 6045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h" 6055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer llvm::SmallString<1024> HeadersFilename(FrameworkName); 6065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HeadersFilename += "Headers/"; 6077412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) { 6087412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 6097412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek // Without trailing '/'. 6107412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); 6117412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 6127412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 613a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 6143cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) { 6151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h" 6175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HeadersFilename = FrameworkName; 6185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HeadersFilename += "PrivateHeaders/"; 6197412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek if (SearchPath != NULL) { 6207412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->clear(); 6217412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek // Without trailing '/'. 6227412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1); 6237412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek } 6247412494982c8b50c90961302c3a718633b2c3ab7Manuel Klimek 625a139481e62fdb209d9d87a54a5733f989d2e8d51Chris Lattner HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end()); 6263cd0128ce49abe658d1858c541e836e57959e04aArgyrios Kyrtzidis if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) 6275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return 0; 6285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 6291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 6305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // This file is a system header or C++ unfriendly if the old file is. 631ca63fa00786e51c207c829f4182f11a6c6b552beTed Kremenek // 632c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner // Note that the temporary 'DirInfo' is required here, as either call to 633c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner // getFileInfo could resize the vector and we don't want to rely on order 634c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner // of evaluation. 635c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo; 636c9dde4f9572423723d9490336799f68050dfefa6Chris Lattner getFileInfo(FE).DirInfo = DirInfo; 6375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return FE; 6385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 6395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 6405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 6415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// File Info Management. 6425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 6435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 6448f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor/// \brief Merge the header file info provided by \p OtherHFI into the current 6458f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor/// header file info (\p HFI) 6468f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregorstatic void mergeHeaderFileInfo(HeaderFileInfo &HFI, 6478f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor const HeaderFileInfo &OtherHFI) { 6488f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.isImport |= OtherHFI.isImport; 6498f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.isPragmaOnce |= OtherHFI.isPragmaOnce; 6508f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.NumIncludes += OtherHFI.NumIncludes; 6518f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor 6528f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (!HFI.ControllingMacro && !HFI.ControllingMacroID) { 6538f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.ControllingMacro = OtherHFI.ControllingMacro; 6548f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.ControllingMacroID = OtherHFI.ControllingMacroID; 6558f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor } 6568f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor 6578f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (OtherHFI.External) { 6588f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.DirInfo = OtherHFI.DirInfo; 6598f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.External = OtherHFI.External; 6608f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.IndexHeaderMapHeader = OtherHFI.IndexHeaderMapHeader; 6618f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor } 6625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 6638f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (HFI.Framework.empty()) 6648f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.Framework = OtherHFI.Framework; 6658f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor 6668f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor HFI.Resolved = true; 6678f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor} 6688f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor 66983d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff/// getFileInfo - Return the HeaderFileInfo structure for the specified 6705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// FileEntry. 67183d63c78810556d26b62ac4cbae2eda6cdd2570cSteve NaroffHeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) { 6725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FE->getUID() >= FileInfo.size()) 6735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FileInfo.resize(FE->getUID()+1); 674cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor 675cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor HeaderFileInfo &HFI = FileInfo[FE->getUID()]; 6768f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (ExternalSource && !HFI.Resolved) 6778f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(FE)); 678cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor return HFI; 6791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump} 6805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 681dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregorbool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) { 682dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor // Check if we've ever seen this file as a header. 683dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor if (File->getUID() >= FileInfo.size()) 684dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor return false; 685dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor 686dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor // Resolve header file info from the external source, if needed. 687dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor HeaderFileInfo &HFI = FileInfo[File->getUID()]; 6888f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor if (ExternalSource && !HFI.Resolved) 6898f8d581f76da8a6bf9de45746f908b970f09ee1bDouglas Gregor mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(File)); 690dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor 691dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor return HFI.isPragmaOnce || HFI.ControllingMacro || HFI.ControllingMacroID; 692dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor} 693dd3e5549e3c11e217078938aacf72f042eea5343Douglas Gregor 69483d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroffvoid HeaderSearch::setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID) { 69583d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff if (UID >= FileInfo.size()) 69683d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff FileInfo.resize(UID+1); 697cfbf1c7536e016dc275139dd842d4a5f059a749fDouglas Gregor HFI.Resolved = true; 69883d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff FileInfo[UID] = HFI; 69983d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff} 70083d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff 7015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// ShouldEnterIncludeFile - Mark the specified file as a target of of a 7025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// #include, #include_next, or #import directive. Return false if #including 7035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// the file will have no effect or true if we should include it. 7045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerbool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){ 7055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ++NumIncluded; // Count # of attempted #includes. 7065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 7075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Get information about this file. 70883d63c78810556d26b62ac4cbae2eda6cdd2570cSteve Naroff HeaderFileInfo &FileInfo = getFileInfo(File); 7091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this is a #import directive, check that we have not already imported 7115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // this header. 7125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (isImport) { 7135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // If this has already been imported, don't import it again. 7145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer FileInfo.isImport = true; 7151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Has this already been #import'ed or #include'd? 7175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FileInfo.NumIncludes) return false; 7185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } else { 7195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Otherwise, if this is a #include of a file that was previously #import'd 7205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // or if this is the second #include of a #pragma once file, ignore it. 7215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (FileInfo.isImport) 7225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return false; 7235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 7241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Next, check to see if the file is wrapped with #ifndef guards. If so, and 7265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // if the macro that guards it is defined, we know the #include has no effect. 7271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (const IdentifierInfo *ControllingMacro 7288c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor = FileInfo.getControllingMacro(ExternalLookup)) 7298c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor if (ControllingMacro->hasMacroDefinition()) { 7308c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor ++NumMultiIncludeFileOptzn; 7318c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor return false; 7328c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor } 7331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Increment the number of times this file has been included. 7355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ++FileInfo.NumIncludes; 7361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 7375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return true; 7385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 7395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 740d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremeneksize_t HeaderSearch::getTotalMemory() const { 741d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek return SearchDirs.capacity() 742eabea45e23abc07e917f0d4bce15054ce75623efTed Kremenek + llvm::capacity_in_bytes(FileInfo) 743eabea45e23abc07e917f0d4bce15054ce75623efTed Kremenek + llvm::capacity_in_bytes(HeaderMaps) 744d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek + LookupFileCache.getAllocator().getTotalMemory() 745d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek + FrameworkMap.getAllocator().getTotalMemory(); 746d1194fbbf65374bfa3578eb40a547e4f97b497d1Ted Kremenek} 74765e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor 74865e02fa80e1c185f18e5f81cefc30d75383a7301Douglas GregorStringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) { 74965e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor return FrameworkNames.GetOrCreateValue(Framework).getKey(); 75065e02fa80e1c185f18e5f81cefc30d75383a7301Douglas Gregor} 751a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 752a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregorbool HeaderSearch::hasModuleMap(StringRef FileName, 753a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor const DirectoryEntry *Root) { 754a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor llvm::SmallVector<const DirectoryEntry *, 2> FixUpDirectories; 755a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 756a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor StringRef DirName = FileName; 757a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor do { 758a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Get the parent directory name. 759a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor DirName = llvm::sys::path::parent_path(DirName); 760a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (DirName.empty()) 761a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return false; 762a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 763a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Determine whether this directory exists. 764a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor const DirectoryEntry *Dir = FileMgr.getDirectory(DirName); 765a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor if (!Dir) 766a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return false; 767a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 768cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // Try to load the module map file in this directory. 76926697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor switch (loadModuleMapFile(Dir)) { 77026697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor case LMM_NewlyLoaded: 77126697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor case LMM_AlreadyLoaded: 772cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // Success. All of the directories we stepped through inherit this module 773cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // map file. 774a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I) 775a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor DirectoryHasModuleMap[FixUpDirectories[I]] = true; 776a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 777a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return true; 77826697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor 77926697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor case LMM_NoDirectory: 78026697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor case LMM_InvalidModuleMap: 78126697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor break; 782a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } 783a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 784cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // If we hit the top of our search, we're done. 785cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (Dir == Root) 786cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor return false; 787cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 788a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // Keep track of all of the directories we checked, so we can mark them as 789a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor // having module maps if we eventually do find a module map. 790a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor FixUpDirectories.push_back(Dir); 791a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor } while (true); 792a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 793a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return false; 794a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 795a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 79665f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas GregorStringRef HeaderSearch::findModuleForHeader(const FileEntry *File) { 79765f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor if (ModuleMap::Module *Module = ModMap.findModuleForHeader(File)) 79865f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor return Module->getTopLevelModuleName(); 79965f3b5e99009f49d51eb00a859dbd2c2ee660718Douglas Gregor 800a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor return StringRef(); 801a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor} 802a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 803db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregorbool HeaderSearch::loadModuleMapFile(const FileEntry *File) { 804db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor const DirectoryEntry *Dir = File->getDir(); 805db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor 806db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir 807db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor = DirectoryHasModuleMap.find(Dir); 808db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor if (KnownDir != DirectoryHasModuleMap.end()) 809db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor return !KnownDir->second; 810db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor 811db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor bool Result = ModMap.parseModuleMapFile(File); 812db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor DirectoryHasModuleMap[Dir] = !Result; 813db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor return Result; 814db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor} 815db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor 816db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas GregorModuleMap::Module *HeaderSearch::getModule(StringRef Name, bool AllowSearch) { 817db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor if (ModuleMap::Module *Module = ModMap.findModule(Name)) 818db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor return Module; 819db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor 820db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor if (!AllowSearch) 821db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor return 0; 822db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor 823db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor for (unsigned I = 0, N = SearchDirs.size(); I != N; ++I) { 824db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor if (!SearchDirs[I].isNormalDir()) 825db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor continue; 826db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor 827db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor switch (loadModuleMapFile(SearchDirs[I].getDir())) { 828db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor case LMM_AlreadyLoaded: 829db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor case LMM_InvalidModuleMap: 830db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor case LMM_NoDirectory: 831db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor break; 832db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor 833db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor case LMM_NewlyLoaded: 834db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor if (ModuleMap::Module *Module = ModMap.findModule(Name)) 835db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor return Module; 836db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor break; 837db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor } 838db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor } 839db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor 840db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor return 0; 841db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor} 842db1cde7dc7bb3aaf48118bd9605192ab94a93635Douglas Gregor 84326697979fb0a4e2b720a0c8d062047edca92bc92Douglas GregorHeaderSearch::LoadModuleMapResult 84426697979fb0a4e2b720a0c8d062047edca92bc92Douglas GregorHeaderSearch::loadModuleMapFile(StringRef DirName) { 845cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (const DirectoryEntry *Dir = FileMgr.getDirectory(DirName)) 846cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor return loadModuleMapFile(Dir); 847cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 84826697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor return LMM_NoDirectory; 849cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor} 850cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 85126697979fb0a4e2b720a0c8d062047edca92bc92Douglas GregorHeaderSearch::LoadModuleMapResult 85226697979fb0a4e2b720a0c8d062047edca92bc92Douglas GregorHeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir) { 853cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir 854cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor = DirectoryHasModuleMap.find(Dir); 855cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (KnownDir != DirectoryHasModuleMap.end()) 85626697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor return KnownDir->second? LMM_AlreadyLoaded : LMM_InvalidModuleMap; 857cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 858cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor llvm::SmallString<128> ModuleMapFileName; 859cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor ModuleMapFileName += Dir->getName(); 860cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor llvm::sys::path::append(ModuleMapFileName, "module.map"); 861cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (const FileEntry *ModuleMapFile = FileMgr.getFile(ModuleMapFileName)) { 862cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // We have found a module map file. Try to parse it. 863cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor if (!ModMap.parseModuleMapFile(ModuleMapFile)) { 864cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // This directory has a module map. 865cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor DirectoryHasModuleMap[Dir] = true; 866cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 86726697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor return LMM_NewlyLoaded; 868cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 869cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor } 870cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor 871cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor // No suitable module map. 872cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor DirectoryHasModuleMap[Dir] = false; 87326697979fb0a4e2b720a0c8d062047edca92bc92Douglas Gregor return LMM_InvalidModuleMap; 874cf70d7873fe3098bdac72e7628f4e832d14d5143Douglas Gregor} 875a30cfe5026b12c28b7b575b48176e0a3543ce939Douglas Gregor 876