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