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