HeaderSearch.cpp revision 249423
1//===--- HeaderSearch.cpp - Resolve Header File Locations ---===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file implements the DirectoryLookup and HeaderSearch interfaces.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Lex/HeaderSearch.h"
15#include "clang/Basic/Diagnostic.h"
16#include "clang/Basic/FileManager.h"
17#include "clang/Basic/IdentifierTable.h"
18#include "clang/Lex/HeaderMap.h"
19#include "clang/Lex/HeaderSearchOptions.h"
20#include "clang/Lex/Lexer.h"
21#include "llvm/ADT/SmallString.h"
22#include "llvm/Support/Capacity.h"
23#include "llvm/Support/FileSystem.h"
24#include "llvm/Support/Path.h"
25#include <cstdio>
26#if defined(LLVM_ON_UNIX)
27#include <limits.h>
28#endif
29using namespace clang;
30
31const IdentifierInfo *
32HeaderFileInfo::getControllingMacro(ExternalIdentifierLookup *External) {
33  if (ControllingMacro)
34    return ControllingMacro;
35
36  if (!ControllingMacroID || !External)
37    return 0;
38
39  ControllingMacro = External->GetIdentifier(ControllingMacroID);
40  return ControllingMacro;
41}
42
43ExternalHeaderFileInfoSource::~ExternalHeaderFileInfoSource() {}
44
45HeaderSearch::HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts,
46                           FileManager &FM, DiagnosticsEngine &Diags,
47                           const LangOptions &LangOpts,
48                           const TargetInfo *Target)
49  : HSOpts(HSOpts), FileMgr(FM), FrameworkMap(64),
50    ModMap(FileMgr, *Diags.getClient(), LangOpts, Target, *this)
51{
52  AngledDirIdx = 0;
53  SystemDirIdx = 0;
54  NoCurDirSearch = false;
55
56  ExternalLookup = 0;
57  ExternalSource = 0;
58  NumIncluded = 0;
59  NumMultiIncludeFileOptzn = 0;
60  NumFrameworkLookups = NumSubFrameworkLookups = 0;
61}
62
63HeaderSearch::~HeaderSearch() {
64  // Delete headermaps.
65  for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
66    delete HeaderMaps[i].second;
67}
68
69void HeaderSearch::PrintStats() {
70  fprintf(stderr, "\n*** HeaderSearch Stats:\n");
71  fprintf(stderr, "%d files tracked.\n", (int)FileInfo.size());
72  unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0;
73  for (unsigned i = 0, e = FileInfo.size(); i != e; ++i) {
74    NumOnceOnlyFiles += FileInfo[i].isImport;
75    if (MaxNumIncludes < FileInfo[i].NumIncludes)
76      MaxNumIncludes = FileInfo[i].NumIncludes;
77    NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1;
78  }
79  fprintf(stderr, "  %d #import/#pragma once files.\n", NumOnceOnlyFiles);
80  fprintf(stderr, "  %d included exactly once.\n", NumSingleIncludedFiles);
81  fprintf(stderr, "  %d max times a file is included.\n", MaxNumIncludes);
82
83  fprintf(stderr, "  %d #include/#include_next/#import.\n", NumIncluded);
84  fprintf(stderr, "    %d #includes skipped due to"
85          " the multi-include optimization.\n", NumMultiIncludeFileOptzn);
86
87  fprintf(stderr, "%d framework lookups.\n", NumFrameworkLookups);
88  fprintf(stderr, "%d subframework lookups.\n", NumSubFrameworkLookups);
89}
90
91/// CreateHeaderMap - This method returns a HeaderMap for the specified
92/// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
93const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) {
94  // We expect the number of headermaps to be small, and almost always empty.
95  // If it ever grows, use of a linear search should be re-evaluated.
96  if (!HeaderMaps.empty()) {
97    for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
98      // Pointer equality comparison of FileEntries works because they are
99      // already uniqued by inode.
100      if (HeaderMaps[i].first == FE)
101        return HeaderMaps[i].second;
102  }
103
104  if (const HeaderMap *HM = HeaderMap::Create(FE, FileMgr)) {
105    HeaderMaps.push_back(std::make_pair(FE, HM));
106    return HM;
107  }
108
109  return 0;
110}
111
112std::string HeaderSearch::getModuleFileName(Module *Module) {
113  // If we don't have a module cache path, we can't do anything.
114  if (ModuleCachePath.empty())
115    return std::string();
116
117
118  SmallString<256> Result(ModuleCachePath);
119  llvm::sys::path::append(Result, Module->getTopLevelModule()->Name + ".pcm");
120  return Result.str().str();
121}
122
123std::string HeaderSearch::getModuleFileName(StringRef ModuleName) {
124  // If we don't have a module cache path, we can't do anything.
125  if (ModuleCachePath.empty())
126    return std::string();
127
128
129  SmallString<256> Result(ModuleCachePath);
130  llvm::sys::path::append(Result, ModuleName + ".pcm");
131  return Result.str().str();
132}
133
134Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) {
135  // Look in the module map to determine if there is a module by this name.
136  Module *Module = ModMap.findModule(ModuleName);
137  if (Module || !AllowSearch)
138    return Module;
139
140  // Look through the various header search paths to load any available module
141  // maps, searching for a module map that describes this module.
142  for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
143    if (SearchDirs[Idx].isFramework()) {
144      // Search for or infer a module map for a framework.
145      SmallString<128> FrameworkDirName;
146      FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName();
147      llvm::sys::path::append(FrameworkDirName, ModuleName + ".framework");
148      if (const DirectoryEntry *FrameworkDir
149            = FileMgr.getDirectory(FrameworkDirName)) {
150        bool IsSystem
151          = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User;
152        Module = loadFrameworkModule(ModuleName, FrameworkDir, IsSystem);
153        if (Module)
154          break;
155      }
156    }
157
158    // FIXME: Figure out how header maps and module maps will work together.
159
160    // Only deal with normal search directories.
161    if (!SearchDirs[Idx].isNormalDir())
162      continue;
163
164    // Search for a module map file in this directory.
165    if (loadModuleMapFile(SearchDirs[Idx].getDir()) == LMM_NewlyLoaded) {
166      // We just loaded a module map file; check whether the module is
167      // available now.
168      Module = ModMap.findModule(ModuleName);
169      if (Module)
170        break;
171    }
172
173    // Search for a module map in a subdirectory with the same name as the
174    // module.
175    SmallString<128> NestedModuleMapDirName;
176    NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName();
177    llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
178    if (loadModuleMapFile(NestedModuleMapDirName) == LMM_NewlyLoaded) {
179      // If we just loaded a module map file, look for the module again.
180      Module = ModMap.findModule(ModuleName);
181      if (Module)
182        break;
183    }
184
185    // If we've already performed the exhaustive search for module maps in this
186    // search directory, don't do it again.
187    if (SearchDirs[Idx].haveSearchedAllModuleMaps())
188      continue;
189
190    // Load all module maps in the immediate subdirectories of this search
191    // directory.
192    loadSubdirectoryModuleMaps(SearchDirs[Idx]);
193
194    // Look again for the module.
195    Module = ModMap.findModule(ModuleName);
196    if (Module)
197      break;
198  }
199
200  return Module;
201}
202
203//===----------------------------------------------------------------------===//
204// File lookup within a DirectoryLookup scope
205//===----------------------------------------------------------------------===//
206
207/// getName - Return the directory or filename corresponding to this lookup
208/// object.
209const char *DirectoryLookup::getName() const {
210  if (isNormalDir())
211    return getDir()->getName();
212  if (isFramework())
213    return getFrameworkDir()->getName();
214  assert(isHeaderMap() && "Unknown DirectoryLookup");
215  return getHeaderMap()->getFileName();
216}
217
218
219/// LookupFile - Lookup the specified file in this search path, returning it
220/// if it exists or returning null if not.
221const FileEntry *DirectoryLookup::LookupFile(
222    StringRef Filename,
223    HeaderSearch &HS,
224    SmallVectorImpl<char> *SearchPath,
225    SmallVectorImpl<char> *RelativePath,
226    Module **SuggestedModule,
227    bool &InUserSpecifiedSystemFramework) const {
228  InUserSpecifiedSystemFramework = false;
229
230  SmallString<1024> TmpDir;
231  if (isNormalDir()) {
232    // Concatenate the requested file onto the directory.
233    TmpDir = getDir()->getName();
234    llvm::sys::path::append(TmpDir, Filename);
235    if (SearchPath != NULL) {
236      StringRef SearchPathRef(getDir()->getName());
237      SearchPath->clear();
238      SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
239    }
240    if (RelativePath != NULL) {
241      RelativePath->clear();
242      RelativePath->append(Filename.begin(), Filename.end());
243    }
244
245    // If we have a module map that might map this header, load it and
246    // check whether we'll have a suggestion for a module.
247    if (SuggestedModule && HS.hasModuleMap(TmpDir, getDir())) {
248      const FileEntry *File = HS.getFileMgr().getFile(TmpDir.str(),
249                                                      /*openFile=*/false);
250      if (!File)
251        return File;
252
253      // If there is a module that corresponds to this header,
254      // suggest it.
255      *SuggestedModule = HS.findModuleForHeader(File);
256      return File;
257    }
258
259    return HS.getFileMgr().getFile(TmpDir.str(), /*openFile=*/true);
260  }
261
262  if (isFramework())
263    return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
264                             SuggestedModule, InUserSpecifiedSystemFramework);
265
266  assert(isHeaderMap() && "Unknown directory lookup");
267  const FileEntry * const Result = getHeaderMap()->LookupFile(
268      Filename, HS.getFileMgr());
269  if (Result) {
270    if (SearchPath != NULL) {
271      StringRef SearchPathRef(getName());
272      SearchPath->clear();
273      SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
274    }
275    if (RelativePath != NULL) {
276      RelativePath->clear();
277      RelativePath->append(Filename.begin(), Filename.end());
278    }
279  }
280  return Result;
281}
282
283/// \brief Given a framework directory, find the top-most framework directory.
284///
285/// \param FileMgr The file manager to use for directory lookups.
286/// \param DirName The name of the framework directory.
287/// \param SubmodulePath Will be populated with the submodule path from the
288/// returned top-level module to the originally named framework.
289static const DirectoryEntry *
290getTopFrameworkDir(FileManager &FileMgr, StringRef DirName,
291                   SmallVectorImpl<std::string> &SubmodulePath) {
292  assert(llvm::sys::path::extension(DirName) == ".framework" &&
293         "Not a framework directory");
294
295  // Note: as an egregious but useful hack we use the real path here, because
296  // frameworks moving between top-level frameworks to embedded frameworks tend
297  // to be symlinked, and we base the logical structure of modules on the
298  // physical layout. In particular, we need to deal with crazy includes like
299  //
300  //   #include <Foo/Frameworks/Bar.framework/Headers/Wibble.h>
301  //
302  // where 'Bar' used to be embedded in 'Foo', is now a top-level framework
303  // which one should access with, e.g.,
304  //
305  //   #include <Bar/Wibble.h>
306  //
307  // Similar issues occur when a top-level framework has moved into an
308  // embedded framework.
309  const DirectoryEntry *TopFrameworkDir = FileMgr.getDirectory(DirName);
310  DirName = FileMgr.getCanonicalName(TopFrameworkDir);
311  do {
312    // Get the parent directory name.
313    DirName = llvm::sys::path::parent_path(DirName);
314    if (DirName.empty())
315      break;
316
317    // Determine whether this directory exists.
318    const DirectoryEntry *Dir = FileMgr.getDirectory(DirName);
319    if (!Dir)
320      break;
321
322    // If this is a framework directory, then we're a subframework of this
323    // framework.
324    if (llvm::sys::path::extension(DirName) == ".framework") {
325      SubmodulePath.push_back(llvm::sys::path::stem(DirName));
326      TopFrameworkDir = Dir;
327    }
328  } while (true);
329
330  return TopFrameworkDir;
331}
332
333/// DoFrameworkLookup - Do a lookup of the specified file in the current
334/// DirectoryLookup, which is a framework directory.
335const FileEntry *DirectoryLookup::DoFrameworkLookup(
336    StringRef Filename,
337    HeaderSearch &HS,
338    SmallVectorImpl<char> *SearchPath,
339    SmallVectorImpl<char> *RelativePath,
340    Module **SuggestedModule,
341    bool &InUserSpecifiedSystemFramework) const
342{
343  FileManager &FileMgr = HS.getFileMgr();
344
345  // Framework names must have a '/' in the filename.
346  size_t SlashPos = Filename.find('/');
347  if (SlashPos == StringRef::npos) return 0;
348
349  // Find out if this is the home for the specified framework, by checking
350  // HeaderSearch.  Possible answers are yes/no and unknown.
351  HeaderSearch::FrameworkCacheEntry &CacheEntry =
352    HS.LookupFrameworkCache(Filename.substr(0, SlashPos));
353
354  // If it is known and in some other directory, fail.
355  if (CacheEntry.Directory && CacheEntry.Directory != getFrameworkDir())
356    return 0;
357
358  // Otherwise, construct the path to this framework dir.
359
360  // FrameworkName = "/System/Library/Frameworks/"
361  SmallString<1024> FrameworkName;
362  FrameworkName += getFrameworkDir()->getName();
363  if (FrameworkName.empty() || FrameworkName.back() != '/')
364    FrameworkName.push_back('/');
365
366  // FrameworkName = "/System/Library/Frameworks/Cocoa"
367  StringRef ModuleName(Filename.begin(), SlashPos);
368  FrameworkName += ModuleName;
369
370  // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/"
371  FrameworkName += ".framework/";
372
373  // If the cache entry was unresolved, populate it now.
374  if (CacheEntry.Directory == 0) {
375    HS.IncrementFrameworkLookupCount();
376
377    // If the framework dir doesn't exist, we fail.
378    const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str());
379    if (Dir == 0) return 0;
380
381    // Otherwise, if it does, remember that this is the right direntry for this
382    // framework.
383    CacheEntry.Directory = getFrameworkDir();
384
385    // If this is a user search directory, check if the framework has been
386    // user-specified as a system framework.
387    if (getDirCharacteristic() == SrcMgr::C_User) {
388      SmallString<1024> SystemFrameworkMarker(FrameworkName);
389      SystemFrameworkMarker += ".system_framework";
390      if (llvm::sys::fs::exists(SystemFrameworkMarker.str())) {
391        CacheEntry.IsUserSpecifiedSystemFramework = true;
392      }
393    }
394  }
395
396  // Set the 'user-specified system framework' flag.
397  InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework;
398
399  if (RelativePath != NULL) {
400    RelativePath->clear();
401    RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
402  }
403
404  // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h"
405  unsigned OrigSize = FrameworkName.size();
406
407  FrameworkName += "Headers/";
408
409  if (SearchPath != NULL) {
410    SearchPath->clear();
411    // Without trailing '/'.
412    SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
413  }
414
415  FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
416  const FileEntry *FE = FileMgr.getFile(FrameworkName.str(),
417                                        /*openFile=*/!SuggestedModule);
418  if (!FE) {
419    // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h"
420    const char *Private = "Private";
421    FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
422                         Private+strlen(Private));
423    if (SearchPath != NULL)
424      SearchPath->insert(SearchPath->begin()+OrigSize, Private,
425                         Private+strlen(Private));
426
427    FE = FileMgr.getFile(FrameworkName.str(), /*openFile=*/!SuggestedModule);
428  }
429
430  // If we found the header and are allowed to suggest a module, do so now.
431  if (FE && SuggestedModule) {
432    // Find the framework in which this header occurs.
433    StringRef FrameworkPath = FE->getName();
434    bool FoundFramework = false;
435    do {
436      // Get the parent directory name.
437      FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
438      if (FrameworkPath.empty())
439        break;
440
441      // Determine whether this directory exists.
442      const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkPath);
443      if (!Dir)
444        break;
445
446      // If this is a framework directory, then we're a subframework of this
447      // framework.
448      if (llvm::sys::path::extension(FrameworkPath) == ".framework") {
449        FoundFramework = true;
450        break;
451      }
452    } while (true);
453
454    if (FoundFramework) {
455      // Find the top-level framework based on this framework.
456      SmallVector<std::string, 4> SubmodulePath;
457      const DirectoryEntry *TopFrameworkDir
458        = ::getTopFrameworkDir(FileMgr, FrameworkPath, SubmodulePath);
459
460      // Determine the name of the top-level framework.
461      StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName());
462
463      // Load this framework module. If that succeeds, find the suggested module
464      // for this header, if any.
465      bool IsSystem = getDirCharacteristic() != SrcMgr::C_User;
466      if (HS.loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystem)) {
467        *SuggestedModule = HS.findModuleForHeader(FE);
468      }
469    } else {
470      *SuggestedModule = HS.findModuleForHeader(FE);
471    }
472  }
473  return FE;
474}
475
476void HeaderSearch::setTarget(const TargetInfo &Target) {
477  ModMap.setTarget(Target);
478}
479
480
481//===----------------------------------------------------------------------===//
482// Header File Location.
483//===----------------------------------------------------------------------===//
484
485
486/// LookupFile - Given a "foo" or \<foo> reference, look up the indicated file,
487/// return null on failure.  isAngled indicates whether the file reference is
488/// for system \#include's or not (i.e. using <> instead of "").  CurFileEnt, if
489/// non-null, indicates where the \#including file is, in case a relative search
490/// is needed.
491const FileEntry *HeaderSearch::LookupFile(
492    StringRef Filename,
493    bool isAngled,
494    const DirectoryLookup *FromDir,
495    const DirectoryLookup *&CurDir,
496    const FileEntry *CurFileEnt,
497    SmallVectorImpl<char> *SearchPath,
498    SmallVectorImpl<char> *RelativePath,
499    Module **SuggestedModule,
500    bool SkipCache)
501{
502  if (SuggestedModule)
503    *SuggestedModule = 0;
504
505  // If 'Filename' is absolute, check to see if it exists and no searching.
506  if (llvm::sys::path::is_absolute(Filename)) {
507    CurDir = 0;
508
509    // If this was an #include_next "/absolute/file", fail.
510    if (FromDir) return 0;
511
512    if (SearchPath != NULL)
513      SearchPath->clear();
514    if (RelativePath != NULL) {
515      RelativePath->clear();
516      RelativePath->append(Filename.begin(), Filename.end());
517    }
518    // Otherwise, just return the file.
519    return FileMgr.getFile(Filename, /*openFile=*/true);
520  }
521
522  // Unless disabled, check to see if the file is in the #includer's
523  // directory.  This has to be based on CurFileEnt, not CurDir, because
524  // CurFileEnt could be a #include of a subdirectory (#include "foo/bar.h") and
525  // a subsequent include of "baz.h" should resolve to "whatever/foo/baz.h".
526  // This search is not done for <> headers.
527  if (CurFileEnt && !isAngled && !NoCurDirSearch) {
528    SmallString<1024> TmpDir;
529    // Concatenate the requested file onto the directory.
530    // FIXME: Portability.  Filename concatenation should be in sys::Path.
531    TmpDir += CurFileEnt->getDir()->getName();
532    TmpDir.push_back('/');
533    TmpDir.append(Filename.begin(), Filename.end());
534    if (const FileEntry *FE = FileMgr.getFile(TmpDir.str(),/*openFile=*/true)) {
535      // Leave CurDir unset.
536      // This file is a system header or C++ unfriendly if the old file is.
537      //
538      // Note that we only use one of FromHFI/ToHFI at once, due to potential
539      // reallocation of the underlying vector potentially making the first
540      // reference binding dangling.
541      HeaderFileInfo &FromHFI = getFileInfo(CurFileEnt);
542      unsigned DirInfo = FromHFI.DirInfo;
543      bool IndexHeaderMapHeader = FromHFI.IndexHeaderMapHeader;
544      StringRef Framework = FromHFI.Framework;
545
546      HeaderFileInfo &ToHFI = getFileInfo(FE);
547      ToHFI.DirInfo = DirInfo;
548      ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader;
549      ToHFI.Framework = Framework;
550
551      if (SearchPath != NULL) {
552        StringRef SearchPathRef(CurFileEnt->getDir()->getName());
553        SearchPath->clear();
554        SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
555      }
556      if (RelativePath != NULL) {
557        RelativePath->clear();
558        RelativePath->append(Filename.begin(), Filename.end());
559      }
560      return FE;
561    }
562  }
563
564  CurDir = 0;
565
566  // If this is a system #include, ignore the user #include locs.
567  unsigned i = isAngled ? AngledDirIdx : 0;
568
569  // If this is a #include_next request, start searching after the directory the
570  // file was found in.
571  if (FromDir)
572    i = FromDir-&SearchDirs[0];
573
574  // Cache all of the lookups performed by this method.  Many headers are
575  // multiply included, and the "pragma once" optimization prevents them from
576  // being relex/pp'd, but they would still have to search through a
577  // (potentially huge) series of SearchDirs to find it.
578  std::pair<unsigned, unsigned> &CacheLookup =
579    LookupFileCache.GetOrCreateValue(Filename).getValue();
580
581  // If the entry has been previously looked up, the first value will be
582  // non-zero.  If the value is equal to i (the start point of our search), then
583  // this is a matching hit.
584  if (!SkipCache && CacheLookup.first == i+1) {
585    // Skip querying potentially lots of directories for this lookup.
586    i = CacheLookup.second;
587  } else {
588    // Otherwise, this is the first query, or the previous query didn't match
589    // our search start.  We will fill in our found location below, so prime the
590    // start point value.
591    CacheLookup.first = i+1;
592  }
593
594  // Check each directory in sequence to see if it contains this file.
595  for (; i != SearchDirs.size(); ++i) {
596    bool InUserSpecifiedSystemFramework = false;
597    const FileEntry *FE =
598      SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath,
599                               SuggestedModule, InUserSpecifiedSystemFramework);
600    if (!FE) continue;
601
602    CurDir = &SearchDirs[i];
603
604    // This file is a system header or C++ unfriendly if the dir is.
605    HeaderFileInfo &HFI = getFileInfo(FE);
606    HFI.DirInfo = CurDir->getDirCharacteristic();
607
608    // If the directory characteristic is User but this framework was
609    // user-specified to be treated as a system framework, promote the
610    // characteristic.
611    if (HFI.DirInfo == SrcMgr::C_User && InUserSpecifiedSystemFramework)
612      HFI.DirInfo = SrcMgr::C_System;
613
614    // If the filename matches a known system header prefix, override
615    // whether the file is a system header.
616    for (unsigned j = SystemHeaderPrefixes.size(); j; --j) {
617      if (Filename.startswith(SystemHeaderPrefixes[j-1].first)) {
618        HFI.DirInfo = SystemHeaderPrefixes[j-1].second ? SrcMgr::C_System
619                                                       : SrcMgr::C_User;
620        break;
621      }
622    }
623
624    // If this file is found in a header map and uses the framework style of
625    // includes, then this header is part of a framework we're building.
626    if (CurDir->isIndexHeaderMap()) {
627      size_t SlashPos = Filename.find('/');
628      if (SlashPos != StringRef::npos) {
629        HFI.IndexHeaderMapHeader = 1;
630        HFI.Framework = getUniqueFrameworkName(StringRef(Filename.begin(),
631                                                         SlashPos));
632      }
633    }
634
635    // Remember this location for the next lookup we do.
636    CacheLookup.second = i;
637    return FE;
638  }
639
640  // If we are including a file with a quoted include "foo.h" from inside
641  // a header in a framework that is currently being built, and we couldn't
642  // resolve "foo.h" any other way, change the include to <Foo/foo.h>, where
643  // "Foo" is the name of the framework in which the including header was found.
644  if (CurFileEnt && !isAngled && Filename.find('/') == StringRef::npos) {
645    HeaderFileInfo &IncludingHFI = getFileInfo(CurFileEnt);
646    if (IncludingHFI.IndexHeaderMapHeader) {
647      SmallString<128> ScratchFilename;
648      ScratchFilename += IncludingHFI.Framework;
649      ScratchFilename += '/';
650      ScratchFilename += Filename;
651
652      const FileEntry *Result = LookupFile(ScratchFilename, /*isAngled=*/true,
653                                           FromDir, CurDir, CurFileEnt,
654                                           SearchPath, RelativePath,
655                                           SuggestedModule);
656      std::pair<unsigned, unsigned> &CacheLookup
657        = LookupFileCache.GetOrCreateValue(Filename).getValue();
658      CacheLookup.second
659        = LookupFileCache.GetOrCreateValue(ScratchFilename).getValue().second;
660      return Result;
661    }
662  }
663
664  // Otherwise, didn't find it. Remember we didn't find this.
665  CacheLookup.second = SearchDirs.size();
666  return 0;
667}
668
669/// LookupSubframeworkHeader - Look up a subframework for the specified
670/// \#include file.  For example, if \#include'ing <HIToolbox/HIToolbox.h> from
671/// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
672/// is a subframework within Carbon.framework.  If so, return the FileEntry
673/// for the designated file, otherwise return null.
674const FileEntry *HeaderSearch::
675LookupSubframeworkHeader(StringRef Filename,
676                         const FileEntry *ContextFileEnt,
677                         SmallVectorImpl<char> *SearchPath,
678                         SmallVectorImpl<char> *RelativePath,
679                         Module **SuggestedModule) {
680  assert(ContextFileEnt && "No context file?");
681
682  // Framework names must have a '/' in the filename.  Find it.
683  // FIXME: Should we permit '\' on Windows?
684  size_t SlashPos = Filename.find('/');
685  if (SlashPos == StringRef::npos) return 0;
686
687  // Look up the base framework name of the ContextFileEnt.
688  const char *ContextName = ContextFileEnt->getName();
689
690  // If the context info wasn't a framework, couldn't be a subframework.
691  const unsigned DotFrameworkLen = 10;
692  const char *FrameworkPos = strstr(ContextName, ".framework");
693  if (FrameworkPos == 0 ||
694      (FrameworkPos[DotFrameworkLen] != '/' &&
695       FrameworkPos[DotFrameworkLen] != '\\'))
696    return 0;
697
698  SmallString<1024> FrameworkName(ContextName, FrameworkPos+DotFrameworkLen+1);
699
700  // Append Frameworks/HIToolbox.framework/
701  FrameworkName += "Frameworks/";
702  FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
703  FrameworkName += ".framework/";
704
705  llvm::StringMapEntry<FrameworkCacheEntry> &CacheLookup =
706    FrameworkMap.GetOrCreateValue(Filename.substr(0, SlashPos));
707
708  // Some other location?
709  if (CacheLookup.getValue().Directory &&
710      CacheLookup.getKeyLength() == FrameworkName.size() &&
711      memcmp(CacheLookup.getKeyData(), &FrameworkName[0],
712             CacheLookup.getKeyLength()) != 0)
713    return 0;
714
715  // Cache subframework.
716  if (CacheLookup.getValue().Directory == 0) {
717    ++NumSubFrameworkLookups;
718
719    // If the framework dir doesn't exist, we fail.
720    const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str());
721    if (Dir == 0) return 0;
722
723    // Otherwise, if it does, remember that this is the right direntry for this
724    // framework.
725    CacheLookup.getValue().Directory = Dir;
726  }
727
728  const FileEntry *FE = 0;
729
730  if (RelativePath != NULL) {
731    RelativePath->clear();
732    RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
733  }
734
735  // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h"
736  SmallString<1024> HeadersFilename(FrameworkName);
737  HeadersFilename += "Headers/";
738  if (SearchPath != NULL) {
739    SearchPath->clear();
740    // Without trailing '/'.
741    SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
742  }
743
744  HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
745  if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) {
746
747    // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h"
748    HeadersFilename = FrameworkName;
749    HeadersFilename += "PrivateHeaders/";
750    if (SearchPath != NULL) {
751      SearchPath->clear();
752      // Without trailing '/'.
753      SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
754    }
755
756    HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
757    if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true)))
758      return 0;
759  }
760
761  // This file is a system header or C++ unfriendly if the old file is.
762  //
763  // Note that the temporary 'DirInfo' is required here, as either call to
764  // getFileInfo could resize the vector and we don't want to rely on order
765  // of evaluation.
766  unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo;
767  getFileInfo(FE).DirInfo = DirInfo;
768
769  // If we're supposed to suggest a module, look for one now.
770  if (SuggestedModule) {
771    // Find the top-level framework based on this framework.
772    FrameworkName.pop_back(); // remove the trailing '/'
773    SmallVector<std::string, 4> SubmodulePath;
774    const DirectoryEntry *TopFrameworkDir
775      = ::getTopFrameworkDir(FileMgr, FrameworkName, SubmodulePath);
776
777    // Determine the name of the top-level framework.
778    StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName());
779
780    // Load this framework module. If that succeeds, find the suggested module
781    // for this header, if any.
782    bool IsSystem = false;
783    if (loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystem)) {
784      *SuggestedModule = findModuleForHeader(FE);
785    }
786  }
787
788  return FE;
789}
790
791/// \brief Helper static function to normalize a path for injection into
792/// a synthetic header.
793/*static*/ std::string
794HeaderSearch::NormalizeDashIncludePath(StringRef File, FileManager &FileMgr) {
795  // Implicit include paths should be resolved relative to the current
796  // working directory first, and then use the regular header search
797  // mechanism. The proper way to handle this is to have the
798  // predefines buffer located at the current working directory, but
799  // it has no file entry. For now, workaround this by using an
800  // absolute path if we find the file here, and otherwise letting
801  // header search handle it.
802  SmallString<128> Path(File);
803  llvm::sys::fs::make_absolute(Path);
804  bool exists;
805  if (llvm::sys::fs::exists(Path.str(), exists) || !exists)
806    Path = File;
807  else if (exists)
808    FileMgr.getFile(File);
809
810  return Lexer::Stringify(Path.str());
811}
812
813//===----------------------------------------------------------------------===//
814// File Info Management.
815//===----------------------------------------------------------------------===//
816
817/// \brief Merge the header file info provided by \p OtherHFI into the current
818/// header file info (\p HFI)
819static void mergeHeaderFileInfo(HeaderFileInfo &HFI,
820                                const HeaderFileInfo &OtherHFI) {
821  HFI.isImport |= OtherHFI.isImport;
822  HFI.isPragmaOnce |= OtherHFI.isPragmaOnce;
823  HFI.isModuleHeader |= OtherHFI.isModuleHeader;
824  HFI.NumIncludes += OtherHFI.NumIncludes;
825
826  if (!HFI.ControllingMacro && !HFI.ControllingMacroID) {
827    HFI.ControllingMacro = OtherHFI.ControllingMacro;
828    HFI.ControllingMacroID = OtherHFI.ControllingMacroID;
829  }
830
831  if (OtherHFI.External) {
832    HFI.DirInfo = OtherHFI.DirInfo;
833    HFI.External = OtherHFI.External;
834    HFI.IndexHeaderMapHeader = OtherHFI.IndexHeaderMapHeader;
835  }
836
837  if (HFI.Framework.empty())
838    HFI.Framework = OtherHFI.Framework;
839
840  HFI.Resolved = true;
841}
842
843/// getFileInfo - Return the HeaderFileInfo structure for the specified
844/// FileEntry.
845HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) {
846  if (FE->getUID() >= FileInfo.size())
847    FileInfo.resize(FE->getUID()+1);
848
849  HeaderFileInfo &HFI = FileInfo[FE->getUID()];
850  if (ExternalSource && !HFI.Resolved)
851    mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(FE));
852  return HFI;
853}
854
855bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) {
856  // Check if we've ever seen this file as a header.
857  if (File->getUID() >= FileInfo.size())
858    return false;
859
860  // Resolve header file info from the external source, if needed.
861  HeaderFileInfo &HFI = FileInfo[File->getUID()];
862  if (ExternalSource && !HFI.Resolved)
863    mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(File));
864
865  return HFI.isPragmaOnce || HFI.isImport ||
866      HFI.ControllingMacro || HFI.ControllingMacroID;
867}
868
869void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE) {
870  if (FE->getUID() >= FileInfo.size())
871    FileInfo.resize(FE->getUID()+1);
872
873  HeaderFileInfo &HFI = FileInfo[FE->getUID()];
874  HFI.isModuleHeader = true;
875}
876
877void HeaderSearch::setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID) {
878  if (UID >= FileInfo.size())
879    FileInfo.resize(UID+1);
880  HFI.Resolved = true;
881  FileInfo[UID] = HFI;
882}
883
884bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){
885  ++NumIncluded; // Count # of attempted #includes.
886
887  // Get information about this file.
888  HeaderFileInfo &FileInfo = getFileInfo(File);
889
890  // If this is a #import directive, check that we have not already imported
891  // this header.
892  if (isImport) {
893    // If this has already been imported, don't import it again.
894    FileInfo.isImport = true;
895
896    // Has this already been #import'ed or #include'd?
897    if (FileInfo.NumIncludes) return false;
898  } else {
899    // Otherwise, if this is a #include of a file that was previously #import'd
900    // or if this is the second #include of a #pragma once file, ignore it.
901    if (FileInfo.isImport)
902      return false;
903  }
904
905  // Next, check to see if the file is wrapped with #ifndef guards.  If so, and
906  // if the macro that guards it is defined, we know the #include has no effect.
907  if (const IdentifierInfo *ControllingMacro
908      = FileInfo.getControllingMacro(ExternalLookup))
909    if (ControllingMacro->hasMacroDefinition()) {
910      ++NumMultiIncludeFileOptzn;
911      return false;
912    }
913
914  // Increment the number of times this file has been included.
915  ++FileInfo.NumIncludes;
916
917  return true;
918}
919
920size_t HeaderSearch::getTotalMemory() const {
921  return SearchDirs.capacity()
922    + llvm::capacity_in_bytes(FileInfo)
923    + llvm::capacity_in_bytes(HeaderMaps)
924    + LookupFileCache.getAllocator().getTotalMemory()
925    + FrameworkMap.getAllocator().getTotalMemory();
926}
927
928StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) {
929  return FrameworkNames.GetOrCreateValue(Framework).getKey();
930}
931
932bool HeaderSearch::hasModuleMap(StringRef FileName,
933                                const DirectoryEntry *Root) {
934  SmallVector<const DirectoryEntry *, 2> FixUpDirectories;
935
936  StringRef DirName = FileName;
937  do {
938    // Get the parent directory name.
939    DirName = llvm::sys::path::parent_path(DirName);
940    if (DirName.empty())
941      return false;
942
943    // Determine whether this directory exists.
944    const DirectoryEntry *Dir = FileMgr.getDirectory(DirName);
945    if (!Dir)
946      return false;
947
948    // Try to load the module map file in this directory.
949    switch (loadModuleMapFile(Dir)) {
950    case LMM_NewlyLoaded:
951    case LMM_AlreadyLoaded:
952      // Success. All of the directories we stepped through inherit this module
953      // map file.
954      for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
955        DirectoryHasModuleMap[FixUpDirectories[I]] = true;
956
957      return true;
958
959    case LMM_NoDirectory:
960    case LMM_InvalidModuleMap:
961      break;
962    }
963
964    // If we hit the top of our search, we're done.
965    if (Dir == Root)
966      return false;
967
968    // Keep track of all of the directories we checked, so we can mark them as
969    // having module maps if we eventually do find a module map.
970    FixUpDirectories.push_back(Dir);
971  } while (true);
972}
973
974Module *HeaderSearch::findModuleForHeader(const FileEntry *File) const {
975  if (ExternalSource) {
976    // Make sure the external source has handled header info about this file,
977    // which includes whether the file is part of a module.
978    (void)getFileInfo(File);
979  }
980  if (Module *Mod = ModMap.findModuleForHeader(File))
981    return Mod;
982
983  return 0;
984}
985
986bool HeaderSearch::loadModuleMapFile(const FileEntry *File) {
987  const DirectoryEntry *Dir = File->getDir();
988
989  llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir
990    = DirectoryHasModuleMap.find(Dir);
991  if (KnownDir != DirectoryHasModuleMap.end())
992    return !KnownDir->second;
993
994  bool Result = ModMap.parseModuleMapFile(File);
995  if (!Result && llvm::sys::path::filename(File->getName()) == "module.map") {
996    // If the file we loaded was a module.map, look for the corresponding
997    // module_private.map.
998    SmallString<128> PrivateFilename(Dir->getName());
999    llvm::sys::path::append(PrivateFilename, "module_private.map");
1000    if (const FileEntry *PrivateFile = FileMgr.getFile(PrivateFilename))
1001      Result = ModMap.parseModuleMapFile(PrivateFile);
1002  }
1003
1004  DirectoryHasModuleMap[Dir] = !Result;
1005  return Result;
1006}
1007
1008Module *HeaderSearch::loadFrameworkModule(StringRef Name,
1009                                          const DirectoryEntry *Dir,
1010                                          bool IsSystem) {
1011  if (Module *Module = ModMap.findModule(Name))
1012    return Module;
1013
1014  // Try to load a module map file.
1015  switch (loadModuleMapFile(Dir)) {
1016  case LMM_InvalidModuleMap:
1017    break;
1018
1019  case LMM_AlreadyLoaded:
1020  case LMM_NoDirectory:
1021    return 0;
1022
1023  case LMM_NewlyLoaded:
1024    return ModMap.findModule(Name);
1025  }
1026
1027  // Figure out the top-level framework directory and the submodule path from
1028  // that top-level framework to the requested framework.
1029  SmallVector<std::string, 2> SubmodulePath;
1030  SubmodulePath.push_back(Name);
1031  const DirectoryEntry *TopFrameworkDir
1032    = ::getTopFrameworkDir(FileMgr, Dir->getName(), SubmodulePath);
1033
1034
1035  // Try to infer a module map from the top-level framework directory.
1036  Module *Result = ModMap.inferFrameworkModule(SubmodulePath.back(),
1037                                               TopFrameworkDir,
1038                                               IsSystem,
1039                                               /*Parent=*/0);
1040  if (!Result)
1041    return 0;
1042
1043  // Follow the submodule path to find the requested (sub)framework module
1044  // within the top-level framework module.
1045  SubmodulePath.pop_back();
1046  while (!SubmodulePath.empty() && Result) {
1047    Result = ModMap.lookupModuleQualified(SubmodulePath.back(), Result);
1048    SubmodulePath.pop_back();
1049  }
1050  return Result;
1051}
1052
1053
1054HeaderSearch::LoadModuleMapResult
1055HeaderSearch::loadModuleMapFile(StringRef DirName) {
1056  if (const DirectoryEntry *Dir = FileMgr.getDirectory(DirName))
1057    return loadModuleMapFile(Dir);
1058
1059  return LMM_NoDirectory;
1060}
1061
1062HeaderSearch::LoadModuleMapResult
1063HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir) {
1064  llvm::DenseMap<const DirectoryEntry *, bool>::iterator KnownDir
1065    = DirectoryHasModuleMap.find(Dir);
1066  if (KnownDir != DirectoryHasModuleMap.end())
1067    return KnownDir->second? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1068
1069  SmallString<128> ModuleMapFileName;
1070  ModuleMapFileName += Dir->getName();
1071  unsigned ModuleMapDirNameLen = ModuleMapFileName.size();
1072  llvm::sys::path::append(ModuleMapFileName, "module.map");
1073  if (const FileEntry *ModuleMapFile = FileMgr.getFile(ModuleMapFileName)) {
1074    // We have found a module map file. Try to parse it.
1075    if (ModMap.parseModuleMapFile(ModuleMapFile)) {
1076      // No suitable module map.
1077      DirectoryHasModuleMap[Dir] = false;
1078      return LMM_InvalidModuleMap;
1079    }
1080
1081    // This directory has a module map.
1082    DirectoryHasModuleMap[Dir] = true;
1083
1084    // Check whether there is a private module map that we need to load as well.
1085    ModuleMapFileName.erase(ModuleMapFileName.begin() + ModuleMapDirNameLen,
1086                            ModuleMapFileName.end());
1087    llvm::sys::path::append(ModuleMapFileName, "module_private.map");
1088    if (const FileEntry *PrivateModuleMapFile
1089                                        = FileMgr.getFile(ModuleMapFileName)) {
1090      if (ModMap.parseModuleMapFile(PrivateModuleMapFile)) {
1091        // No suitable module map.
1092        DirectoryHasModuleMap[Dir] = false;
1093        return LMM_InvalidModuleMap;
1094      }
1095    }
1096
1097    return LMM_NewlyLoaded;
1098  }
1099
1100  // No suitable module map.
1101  DirectoryHasModuleMap[Dir] = false;
1102  return LMM_InvalidModuleMap;
1103}
1104
1105void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) {
1106  Modules.clear();
1107
1108  // Load module maps for each of the header search directories.
1109  for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
1110    if (SearchDirs[Idx].isFramework()) {
1111      llvm::error_code EC;
1112      SmallString<128> DirNative;
1113      llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(),
1114                              DirNative);
1115
1116      // Search each of the ".framework" directories to load them as modules.
1117      bool IsSystem = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User;
1118      for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd;
1119           Dir != DirEnd && !EC; Dir.increment(EC)) {
1120        if (llvm::sys::path::extension(Dir->path()) != ".framework")
1121          continue;
1122
1123        const DirectoryEntry *FrameworkDir = FileMgr.getDirectory(Dir->path());
1124        if (!FrameworkDir)
1125          continue;
1126
1127        // Load this framework module.
1128        loadFrameworkModule(llvm::sys::path::stem(Dir->path()), FrameworkDir,
1129                            IsSystem);
1130      }
1131      continue;
1132    }
1133
1134    // FIXME: Deal with header maps.
1135    if (SearchDirs[Idx].isHeaderMap())
1136      continue;
1137
1138    // Try to load a module map file for the search directory.
1139    loadModuleMapFile(SearchDirs[Idx].getDir());
1140
1141    // Try to load module map files for immediate subdirectories of this search
1142    // directory.
1143    loadSubdirectoryModuleMaps(SearchDirs[Idx]);
1144  }
1145
1146  // Populate the list of modules.
1147  for (ModuleMap::module_iterator M = ModMap.module_begin(),
1148                               MEnd = ModMap.module_end();
1149       M != MEnd; ++M) {
1150    Modules.push_back(M->getValue());
1151  }
1152}
1153
1154void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) {
1155  if (SearchDir.haveSearchedAllModuleMaps())
1156    return;
1157
1158  llvm::error_code EC;
1159  SmallString<128> DirNative;
1160  llvm::sys::path::native(SearchDir.getDir()->getName(), DirNative);
1161  for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd;
1162       Dir != DirEnd && !EC; Dir.increment(EC)) {
1163    loadModuleMapFile(Dir->path());
1164  }
1165
1166  SearchDir.setSearchedAllModuleMaps(true);
1167}
1168