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