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/Lex/HeaderMap.h"
16 #include "clang/Basic/Diagnostic.h"
17 #include "clang/Basic/FileManager.h"
18 #include "clang/Basic/IdentifierTable.h"
19 #include "llvm/Support/FileSystem.h"
20 #include "llvm/Support/Path.h"
21 #include "llvm/ADT/SmallString.h"
22 #include "llvm/Support/Capacity.h"
23 #include <cstdio>
24 using namespace clang;
25 
26 const IdentifierInfo *
27 HeaderFileInfo::getControllingMacro(ExternalIdentifierLookup *External) {
28   if (ControllingMacro)
29     return ControllingMacro;
30 
31   if (!ControllingMacroID || !External)
32     return 0;
33 
34   ControllingMacro = External->GetIdentifier(ControllingMacroID);
35   return ControllingMacro;
36 }
37 
38 ExternalHeaderFileInfoSource::~ExternalHeaderFileInfoSource() {}
39 
40 HeaderSearch::HeaderSearch(FileManager &FM, DiagnosticsEngine &Diags)
41   : FileMgr(FM), Diags(Diags), FrameworkMap(64),
42     ModMap(FileMgr, *Diags.getClient())
43 {
44   AngledDirIdx = 0;
45   SystemDirIdx = 0;
46   NoCurDirSearch = false;
47 
48   ExternalLookup = 0;
49   ExternalSource = 0;
50   NumIncluded = 0;
51   NumMultiIncludeFileOptzn = 0;
52   NumFrameworkLookups = NumSubFrameworkLookups = 0;
53 }
54 
55 HeaderSearch::~HeaderSearch() {
56   // Delete headermaps.
57   for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
58     delete HeaderMaps[i].second;
59 }
60 
61 void HeaderSearch::PrintStats() {
62   fprintf(stderr, "\n*** HeaderSearch Stats:\n");
63   fprintf(stderr, "%d files tracked.\n", (int)FileInfo.size());
64   unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0;
65   for (unsigned i = 0, e = FileInfo.size(); i != e; ++i) {
66     NumOnceOnlyFiles += FileInfo[i].isImport;
67     if (MaxNumIncludes < FileInfo[i].NumIncludes)
68       MaxNumIncludes = FileInfo[i].NumIncludes;
69     NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1;
70   }
71   fprintf(stderr, "  %d #import/#pragma once files.\n", NumOnceOnlyFiles);
72   fprintf(stderr, "  %d included exactly once.\n", NumSingleIncludedFiles);
73   fprintf(stderr, "  %d max times a file is included.\n", MaxNumIncludes);
74 
75   fprintf(stderr, "  %d #include/#include_next/#import.\n", NumIncluded);
76   fprintf(stderr, "    %d #includes skipped due to"
77           " the multi-include optimization.\n", NumMultiIncludeFileOptzn);
78 
79   fprintf(stderr, "%d framework lookups.\n", NumFrameworkLookups);
80   fprintf(stderr, "%d subframework lookups.\n", NumSubFrameworkLookups);
81 }
82 
83 /// CreateHeaderMap - This method returns a HeaderMap for the specified
84 /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure.
85 const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) {
86   // We expect the number of headermaps to be small, and almost always empty.
87   // If it ever grows, use of a linear search should be re-evaluated.
88   if (!HeaderMaps.empty()) {
89     for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
90       // Pointer equality comparison of FileEntries works because they are
91       // already uniqued by inode.
92       if (HeaderMaps[i].first == FE)
93         return HeaderMaps[i].second;
94   }
95 
96   if (const HeaderMap *HM = HeaderMap::Create(FE, FileMgr)) {
97     HeaderMaps.push_back(std::make_pair(FE, HM));
98     return HM;
99   }
100 
101   return 0;
102 }
103 
104 const FileEntry *HeaderSearch::lookupModule(StringRef ModuleName,
105                                             std::string *ModuleFileName,
106                                             std::string *UmbrellaHeader) {
107   // If we don't have a module cache path, we can't do anything.
108   if (ModuleCachePath.empty()) {
109     if (ModuleFileName)
110       ModuleFileName->clear();
111     return 0;
112   }
113 
114   // Try to find the module path.
115   llvm::SmallString<256> FileName(ModuleCachePath);
116   llvm::sys::path::append(FileName, ModuleName + ".pcm");
117   if (ModuleFileName)
118     *ModuleFileName = FileName.str();
119 
120   if (const FileEntry *ModuleFile
121         = getFileMgr().getFile(FileName, /*OpenFile=*/false,
122                                /*CacheFailure=*/false))
123     return ModuleFile;
124 
125   // We didn't find the module. If we're not supposed to look for an
126   // umbrella header, this is the end of the road.
127   if (!UmbrellaHeader)
128     return 0;
129 
130   // Look in the module map to determine if there is a module by this name
131   // that has an umbrella header.
132   // FIXME: Even if it doesn't have an umbrella header, we should be able to
133   // handle the module. However, the caller isn't ready for that yet.
134   if (ModuleMap::Module *Module = ModMap.findModule(ModuleName)) {
135     if (Module->UmbrellaHeader) {
136       *UmbrellaHeader = Module->UmbrellaHeader->getName();
137       return 0;
138     }
139   }
140 
141   // Look in each of the framework directories for an umbrella header with
142   // the same name as the module.
143   llvm::SmallString<128> UmbrellaHeaderName;
144   UmbrellaHeaderName = ModuleName;
145   UmbrellaHeaderName += '/';
146   UmbrellaHeaderName += ModuleName;
147   UmbrellaHeaderName += ".h";
148   for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
149     // Skip non-framework include paths
150     if (!SearchDirs[Idx].isFramework())
151       continue;
152 
153     // Look for the umbrella header in this directory.
154     if (const FileEntry *HeaderFile
155           = SearchDirs[Idx].LookupFile(UmbrellaHeaderName, *this, 0, 0,
156                                        StringRef(), 0)) {
157       *UmbrellaHeader = HeaderFile->getName();
158       return 0;
159     }
160   }
161 
162   // We did not find an umbrella header. Clear out the UmbrellaHeader pointee
163   // so our caller knows that we failed.
164   UmbrellaHeader->clear();
165   return 0;
166 }
167 
168 //===----------------------------------------------------------------------===//
169 // File lookup within a DirectoryLookup scope
170 //===----------------------------------------------------------------------===//
171 
172 /// getName - Return the directory or filename corresponding to this lookup
173 /// object.
174 const char *DirectoryLookup::getName() const {
175   if (isNormalDir())
176     return getDir()->getName();
177   if (isFramework())
178     return getFrameworkDir()->getName();
179   assert(isHeaderMap() && "Unknown DirectoryLookup");
180   return getHeaderMap()->getFileName();
181 }
182 
183 
184 /// LookupFile - Lookup the specified file in this search path, returning it
185 /// if it exists or returning null if not.
186 const FileEntry *DirectoryLookup::LookupFile(
187     StringRef Filename,
188     HeaderSearch &HS,
189     SmallVectorImpl<char> *SearchPath,
190     SmallVectorImpl<char> *RelativePath,
191     StringRef BuildingModule,
192     StringRef *SuggestedModule) const {
193   llvm::SmallString<1024> TmpDir;
194   if (isNormalDir()) {
195     // Concatenate the requested file onto the directory.
196     TmpDir = getDir()->getName();
197     llvm::sys::path::append(TmpDir, Filename);
198     if (SearchPath != NULL) {
199       StringRef SearchPathRef(getDir()->getName());
200       SearchPath->clear();
201       SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
202     }
203     if (RelativePath != NULL) {
204       RelativePath->clear();
205       RelativePath->append(Filename.begin(), Filename.end());
206     }
207 
208     // If we have a module map that might map this header, load it and
209     // check whether we'll have a suggestion for a module.
210     if (SuggestedModule && HS.hasModuleMap(TmpDir, getDir())) {
211       const FileEntry *File = HS.getFileMgr().getFile(TmpDir.str(),
212                                                       /*openFile=*/false);
213       if (!File)
214         return File;
215 
216       // If there is a module that corresponds to this header,
217       // suggest it.
218       StringRef Module = HS.findModuleForHeader(File);
219       if (!Module.empty() && Module != BuildingModule)
220         *SuggestedModule = Module;
221 
222       return File;
223     }
224 
225     return HS.getFileMgr().getFile(TmpDir.str(), /*openFile=*/true);
226   }
227 
228   if (isFramework())
229     return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
230                              BuildingModule, SuggestedModule);
231 
232   assert(isHeaderMap() && "Unknown directory lookup");
233   const FileEntry * const Result = getHeaderMap()->LookupFile(
234       Filename, HS.getFileMgr());
235   if (Result) {
236     if (SearchPath != NULL) {
237       StringRef SearchPathRef(getName());
238       SearchPath->clear();
239       SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
240     }
241     if (RelativePath != NULL) {
242       RelativePath->clear();
243       RelativePath->append(Filename.begin(), Filename.end());
244     }
245   }
246   return Result;
247 }
248 
249 
250 /// DoFrameworkLookup - Do a lookup of the specified file in the current
251 /// DirectoryLookup, which is a framework directory.
252 const FileEntry *DirectoryLookup::DoFrameworkLookup(
253     StringRef Filename,
254     HeaderSearch &HS,
255     SmallVectorImpl<char> *SearchPath,
256     SmallVectorImpl<char> *RelativePath,
257     StringRef BuildingModule,
258     StringRef *SuggestedModule) const
259 {
260   FileManager &FileMgr = HS.getFileMgr();
261 
262   // Framework names must have a '/' in the filename.
263   size_t SlashPos = Filename.find('/');
264   if (SlashPos == StringRef::npos) return 0;
265 
266   // Find out if this is the home for the specified framework, by checking
267   // HeaderSearch.  Possible answer are yes/no and unknown.
268   const DirectoryEntry *&FrameworkDirCache =
269     HS.LookupFrameworkCache(Filename.substr(0, SlashPos));
270 
271   // If it is known and in some other directory, fail.
272   if (FrameworkDirCache && FrameworkDirCache != getFrameworkDir())
273     return 0;
274 
275   // Otherwise, construct the path to this framework dir.
276 
277   // FrameworkName = "/System/Library/Frameworks/"
278   llvm::SmallString<1024> FrameworkName;
279   FrameworkName += getFrameworkDir()->getName();
280   if (FrameworkName.empty() || FrameworkName.back() != '/')
281     FrameworkName.push_back('/');
282 
283   // FrameworkName = "/System/Library/Frameworks/Cocoa"
284   FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
285 
286   // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/"
287   FrameworkName += ".framework/";
288 
289   // If the cache entry is still unresolved, query to see if the cache entry is
290   // still unresolved.  If so, check its existence now.
291   if (FrameworkDirCache == 0) {
292     HS.IncrementFrameworkLookupCount();
293 
294     // If the framework dir doesn't exist, we fail.
295     // FIXME: It's probably more efficient to query this with FileMgr.getDir.
296     bool Exists;
297     if (llvm::sys::fs::exists(FrameworkName.str(), Exists) || !Exists)
298       return 0;
299 
300     // Otherwise, if it does, remember that this is the right direntry for this
301     // framework.
302     FrameworkDirCache = getFrameworkDir();
303   }
304 
305   if (RelativePath != NULL) {
306     RelativePath->clear();
307     RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
308   }
309 
310   // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h"
311   unsigned OrigSize = FrameworkName.size();
312 
313   FrameworkName += "Headers/";
314 
315   if (SearchPath != NULL) {
316     SearchPath->clear();
317     // Without trailing '/'.
318     SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
319   }
320 
321   /// Determine whether this is the module we're building or not.
322   bool AutomaticImport = SuggestedModule &&
323     (BuildingModule != StringRef(Filename.begin(), SlashPos)) &&
324     !Filename.substr(SlashPos + 1).startswith("..");
325 
326   FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
327   if (const FileEntry *FE = FileMgr.getFile(FrameworkName.str(),
328                                             /*openFile=*/!AutomaticImport)) {
329     if (AutomaticImport)
330       *SuggestedModule = StringRef(Filename.begin(), SlashPos);
331     return FE;
332   }
333 
334   // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h"
335   const char *Private = "Private";
336   FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
337                        Private+strlen(Private));
338   if (SearchPath != NULL)
339     SearchPath->insert(SearchPath->begin()+OrigSize, Private,
340                        Private+strlen(Private));
341 
342   const FileEntry *FE = FileMgr.getFile(FrameworkName.str(),
343                                         /*openFile=*/!AutomaticImport);
344   if (FE && AutomaticImport)
345     *SuggestedModule = StringRef(Filename.begin(), SlashPos);
346   return FE;
347 }
348 
349 
350 //===----------------------------------------------------------------------===//
351 // Header File Location.
352 //===----------------------------------------------------------------------===//
353 
354 
355 /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
356 /// return null on failure.  isAngled indicates whether the file reference is
357 /// for system #include's or not (i.e. using <> instead of "").  CurFileEnt, if
358 /// non-null, indicates where the #including file is, in case a relative search
359 /// is needed.
360 const FileEntry *HeaderSearch::LookupFile(
361     StringRef Filename,
362     bool isAngled,
363     const DirectoryLookup *FromDir,
364     const DirectoryLookup *&CurDir,
365     const FileEntry *CurFileEnt,
366     SmallVectorImpl<char> *SearchPath,
367     SmallVectorImpl<char> *RelativePath,
368     StringRef *SuggestedModule)
369 {
370   if (SuggestedModule)
371     *SuggestedModule = StringRef();
372 
373   // If 'Filename' is absolute, check to see if it exists and no searching.
374   if (llvm::sys::path::is_absolute(Filename)) {
375     CurDir = 0;
376 
377     // If this was an #include_next "/absolute/file", fail.
378     if (FromDir) return 0;
379 
380     if (SearchPath != NULL)
381       SearchPath->clear();
382     if (RelativePath != NULL) {
383       RelativePath->clear();
384       RelativePath->append(Filename.begin(), Filename.end());
385     }
386     // Otherwise, just return the file.
387     return FileMgr.getFile(Filename, /*openFile=*/true);
388   }
389 
390   // Unless disabled, check to see if the file is in the #includer's
391   // directory.  This has to be based on CurFileEnt, not CurDir, because
392   // CurFileEnt could be a #include of a subdirectory (#include "foo/bar.h") and
393   // a subsequent include of "baz.h" should resolve to "whatever/foo/baz.h".
394   // This search is not done for <> headers.
395   if (CurFileEnt && !isAngled && !NoCurDirSearch) {
396     llvm::SmallString<1024> TmpDir;
397     // Concatenate the requested file onto the directory.
398     // FIXME: Portability.  Filename concatenation should be in sys::Path.
399     TmpDir += CurFileEnt->getDir()->getName();
400     TmpDir.push_back('/');
401     TmpDir.append(Filename.begin(), Filename.end());
402     if (const FileEntry *FE = FileMgr.getFile(TmpDir.str(),/*openFile=*/true)) {
403       // Leave CurDir unset.
404       // This file is a system header or C++ unfriendly if the old file is.
405       //
406       // Note that the temporary 'DirInfo' is required here, as either call to
407       // getFileInfo could resize the vector and we don't want to rely on order
408       // of evaluation.
409       unsigned DirInfo = getFileInfo(CurFileEnt).DirInfo;
410       getFileInfo(FE).DirInfo = DirInfo;
411       if (SearchPath != NULL) {
412         StringRef SearchPathRef(CurFileEnt->getDir()->getName());
413         SearchPath->clear();
414         SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
415       }
416       if (RelativePath != NULL) {
417         RelativePath->clear();
418         RelativePath->append(Filename.begin(), Filename.end());
419       }
420       return FE;
421     }
422   }
423 
424   CurDir = 0;
425 
426   // If this is a system #include, ignore the user #include locs.
427   unsigned i = isAngled ? AngledDirIdx : 0;
428 
429   // If this is a #include_next request, start searching after the directory the
430   // file was found in.
431   if (FromDir)
432     i = FromDir-&SearchDirs[0];
433 
434   // Cache all of the lookups performed by this method.  Many headers are
435   // multiply included, and the "pragma once" optimization prevents them from
436   // being relex/pp'd, but they would still have to search through a
437   // (potentially huge) series of SearchDirs to find it.
438   std::pair<unsigned, unsigned> &CacheLookup =
439     LookupFileCache.GetOrCreateValue(Filename).getValue();
440 
441   // If the entry has been previously looked up, the first value will be
442   // non-zero.  If the value is equal to i (the start point of our search), then
443   // this is a matching hit.
444   if (CacheLookup.first == i+1) {
445     // Skip querying potentially lots of directories for this lookup.
446     i = CacheLookup.second;
447   } else {
448     // Otherwise, this is the first query, or the previous query didn't match
449     // our search start.  We will fill in our found location below, so prime the
450     // start point value.
451     CacheLookup.first = i+1;
452   }
453 
454   // Check each directory in sequence to see if it contains this file.
455   for (; i != SearchDirs.size(); ++i) {
456     const FileEntry *FE =
457       SearchDirs[i].LookupFile(Filename, *this, SearchPath, RelativePath,
458                                BuildingModule, SuggestedModule);
459     if (!FE) continue;
460 
461     CurDir = &SearchDirs[i];
462 
463     // This file is a system header or C++ unfriendly if the dir is.
464     HeaderFileInfo &HFI = getFileInfo(FE);
465     HFI.DirInfo = CurDir->getDirCharacteristic();
466 
467     // If this file is found in a header map and uses the framework style of
468     // includes, then this header is part of a framework we're building.
469     if (CurDir->isIndexHeaderMap()) {
470       size_t SlashPos = Filename.find('/');
471       if (SlashPos != StringRef::npos) {
472         HFI.IndexHeaderMapHeader = 1;
473         HFI.Framework = getUniqueFrameworkName(StringRef(Filename.begin(),
474                                                          SlashPos));
475       }
476     }
477 
478     // Remember this location for the next lookup we do.
479     CacheLookup.second = i;
480     return FE;
481   }
482 
483   // If we are including a file with a quoted include "foo.h" from inside
484   // a header in a framework that is currently being built, and we couldn't
485   // resolve "foo.h" any other way, change the include to <Foo/foo.h>, where
486   // "Foo" is the name of the framework in which the including header was found.
487   if (CurFileEnt && !isAngled && Filename.find('/') == StringRef::npos) {
488     HeaderFileInfo &IncludingHFI = getFileInfo(CurFileEnt);
489     if (IncludingHFI.IndexHeaderMapHeader) {
490       llvm::SmallString<128> ScratchFilename;
491       ScratchFilename += IncludingHFI.Framework;
492       ScratchFilename += '/';
493       ScratchFilename += Filename;
494 
495       const FileEntry *Result = LookupFile(ScratchFilename, /*isAngled=*/true,
496                                            FromDir, CurDir, CurFileEnt,
497                                            SearchPath, RelativePath,
498                                            SuggestedModule);
499       std::pair<unsigned, unsigned> &CacheLookup
500         = LookupFileCache.GetOrCreateValue(Filename).getValue();
501       CacheLookup.second
502         = LookupFileCache.GetOrCreateValue(ScratchFilename).getValue().second;
503       return Result;
504     }
505   }
506 
507   // Otherwise, didn't find it. Remember we didn't find this.
508   CacheLookup.second = SearchDirs.size();
509   return 0;
510 }
511 
512 /// LookupSubframeworkHeader - Look up a subframework for the specified
513 /// #include file.  For example, if #include'ing <HIToolbox/HIToolbox.h> from
514 /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
515 /// is a subframework within Carbon.framework.  If so, return the FileEntry
516 /// for the designated file, otherwise return null.
517 const FileEntry *HeaderSearch::
518 LookupSubframeworkHeader(StringRef Filename,
519                          const FileEntry *ContextFileEnt,
520                          SmallVectorImpl<char> *SearchPath,
521                          SmallVectorImpl<char> *RelativePath) {
522   assert(ContextFileEnt && "No context file?");
523 
524   // Framework names must have a '/' in the filename.  Find it.
525   size_t SlashPos = Filename.find('/');
526   if (SlashPos == StringRef::npos) return 0;
527 
528   // Look up the base framework name of the ContextFileEnt.
529   const char *ContextName = ContextFileEnt->getName();
530 
531   // If the context info wasn't a framework, couldn't be a subframework.
532   const char *FrameworkPos = strstr(ContextName, ".framework/");
533   if (FrameworkPos == 0)
534     return 0;
535 
536   llvm::SmallString<1024> FrameworkName(ContextName,
537                                         FrameworkPos+strlen(".framework/"));
538 
539   // Append Frameworks/HIToolbox.framework/
540   FrameworkName += "Frameworks/";
541   FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
542   FrameworkName += ".framework/";
543 
544   llvm::StringMapEntry<const DirectoryEntry *> &CacheLookup =
545     FrameworkMap.GetOrCreateValue(Filename.substr(0, SlashPos));
546 
547   // Some other location?
548   if (CacheLookup.getValue() &&
549       CacheLookup.getKeyLength() == FrameworkName.size() &&
550       memcmp(CacheLookup.getKeyData(), &FrameworkName[0],
551              CacheLookup.getKeyLength()) != 0)
552     return 0;
553 
554   // Cache subframework.
555   if (CacheLookup.getValue() == 0) {
556     ++NumSubFrameworkLookups;
557 
558     // If the framework dir doesn't exist, we fail.
559     const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str());
560     if (Dir == 0) return 0;
561 
562     // Otherwise, if it does, remember that this is the right direntry for this
563     // framework.
564     CacheLookup.setValue(Dir);
565   }
566 
567   const FileEntry *FE = 0;
568 
569   if (RelativePath != NULL) {
570     RelativePath->clear();
571     RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
572   }
573 
574   // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h"
575   llvm::SmallString<1024> HeadersFilename(FrameworkName);
576   HeadersFilename += "Headers/";
577   if (SearchPath != NULL) {
578     SearchPath->clear();
579     // Without trailing '/'.
580     SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
581   }
582 
583   HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
584   if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) {
585 
586     // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h"
587     HeadersFilename = FrameworkName;
588     HeadersFilename += "PrivateHeaders/";
589     if (SearchPath != NULL) {
590       SearchPath->clear();
591       // Without trailing '/'.
592       SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
593     }
594 
595     HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
596     if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true)))
597       return 0;
598   }
599 
600   // This file is a system header or C++ unfriendly if the old file is.
601   //
602   // Note that the temporary 'DirInfo' is required here, as either call to
603   // getFileInfo could resize the vector and we don't want to rely on order
604   // of evaluation.
605   unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo;
606   getFileInfo(FE).DirInfo = DirInfo;
607   return FE;
608 }
609 
610 //===----------------------------------------------------------------------===//
611 // File Info Management.
612 //===----------------------------------------------------------------------===//
613 
614 /// \brief Merge the header file info provided by \p OtherHFI into the current
615 /// header file info (\p HFI)
616 static void mergeHeaderFileInfo(HeaderFileInfo &HFI,
617                                 const HeaderFileInfo &OtherHFI) {
618   HFI.isImport |= OtherHFI.isImport;
619   HFI.isPragmaOnce |= OtherHFI.isPragmaOnce;
620   HFI.NumIncludes += OtherHFI.NumIncludes;
621 
622   if (!HFI.ControllingMacro && !HFI.ControllingMacroID) {
623     HFI.ControllingMacro = OtherHFI.ControllingMacro;
624     HFI.ControllingMacroID = OtherHFI.ControllingMacroID;
625   }
626 
627   if (OtherHFI.External) {
628     HFI.DirInfo = OtherHFI.DirInfo;
629     HFI.External = OtherHFI.External;
630     HFI.IndexHeaderMapHeader = OtherHFI.IndexHeaderMapHeader;
631   }
632 
633   if (HFI.Framework.empty())
634     HFI.Framework = OtherHFI.Framework;
635 
636   HFI.Resolved = true;
637 }
638 
639 /// getFileInfo - Return the HeaderFileInfo structure for the specified
640 /// FileEntry.
641 HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) {
642   if (FE->getUID() >= FileInfo.size())
643     FileInfo.resize(FE->getUID()+1);
644 
645   HeaderFileInfo &HFI = FileInfo[FE->getUID()];
646   if (ExternalSource && !HFI.Resolved)
647     mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(FE));
648   return HFI;
649 }
650 
651 bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) {
652   // Check if we've ever seen this file as a header.
653   if (File->getUID() >= FileInfo.size())
654     return false;
655 
656   // Resolve header file info from the external source, if needed.
657   HeaderFileInfo &HFI = FileInfo[File->getUID()];
658   if (ExternalSource && !HFI.Resolved)
659     mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(File));
660 
661   return HFI.isPragmaOnce || HFI.ControllingMacro || HFI.ControllingMacroID;
662 }
663 
664 void HeaderSearch::setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID) {
665   if (UID >= FileInfo.size())
666     FileInfo.resize(UID+1);
667   HFI.Resolved = true;
668   FileInfo[UID] = HFI;
669 }
670 
671 /// ShouldEnterIncludeFile - Mark the specified file as a target of of a
672 /// #include, #include_next, or #import directive.  Return false if #including
673 /// the file will have no effect or true if we should include it.
674 bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){
675   ++NumIncluded; // Count # of attempted #includes.
676 
677   // Get information about this file.
678   HeaderFileInfo &FileInfo = getFileInfo(File);
679 
680   // If this is a #import directive, check that we have not already imported
681   // this header.
682   if (isImport) {
683     // If this has already been imported, don't import it again.
684     FileInfo.isImport = true;
685 
686     // Has this already been #import'ed or #include'd?
687     if (FileInfo.NumIncludes) return false;
688   } else {
689     // Otherwise, if this is a #include of a file that was previously #import'd
690     // or if this is the second #include of a #pragma once file, ignore it.
691     if (FileInfo.isImport)
692       return false;
693   }
694 
695   // Next, check to see if the file is wrapped with #ifndef guards.  If so, and
696   // if the macro that guards it is defined, we know the #include has no effect.
697   if (const IdentifierInfo *ControllingMacro
698       = FileInfo.getControllingMacro(ExternalLookup))
699     if (ControllingMacro->hasMacroDefinition()) {
700       ++NumMultiIncludeFileOptzn;
701       return false;
702     }
703 
704   // Increment the number of times this file has been included.
705   ++FileInfo.NumIncludes;
706 
707   return true;
708 }
709 
710 size_t HeaderSearch::getTotalMemory() const {
711   return SearchDirs.capacity()
712     + llvm::capacity_in_bytes(FileInfo)
713     + llvm::capacity_in_bytes(HeaderMaps)
714     + LookupFileCache.getAllocator().getTotalMemory()
715     + FrameworkMap.getAllocator().getTotalMemory();
716 }
717 
718 StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) {
719   return FrameworkNames.GetOrCreateValue(Framework).getKey();
720 }
721 
722 bool HeaderSearch::hasModuleMap(StringRef FileName,
723                                 const DirectoryEntry *Root) {
724   llvm::SmallVector<const DirectoryEntry *, 2> FixUpDirectories;
725 
726   StringRef DirName = FileName;
727   do {
728     // Get the parent directory name.
729     DirName = llvm::sys::path::parent_path(DirName);
730     if (DirName.empty())
731       return false;
732 
733     // Determine whether this directory exists.
734     const DirectoryEntry *Dir = FileMgr.getDirectory(DirName);
735     if (!Dir)
736       return false;
737 
738     llvm::DenseMap<const DirectoryEntry *, bool>::iterator
739       KnownDir = DirectoryHasModuleMap.find(Dir);
740     if (KnownDir != DirectoryHasModuleMap.end()) {
741       // We have seen this directory before. If it has no module map file,
742       // we're done.
743       if (!KnownDir->second)
744         return false;
745 
746       // All of the directories we stepped through inherit this module map
747       // file.
748       for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
749         DirectoryHasModuleMap[FixUpDirectories[I]] = true;
750 
751       return true;
752     }
753 
754     // We have not checked for a module map file in this directory yet;
755     // do so now.
756     llvm::SmallString<128> ModuleMapFileName;
757     ModuleMapFileName += Dir->getName();
758     llvm::sys::path::append(ModuleMapFileName, "module.map");
759     if (const FileEntry *ModuleMapFile = FileMgr.getFile(ModuleMapFileName)) {
760       // We have found a module map file. Try to parse it.
761       if (!ModMap.parseModuleMapFile(ModuleMapFile)) {
762         // This directory has a module map.
763         DirectoryHasModuleMap[Dir] = true;
764 
765         // All of the directories we stepped through inherit this module map
766         // file.
767         for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
768           DirectoryHasModuleMap[FixUpDirectories[I]] = true;
769 
770         return true;
771       }
772     }
773 
774     // This directory did not have a module map file.
775     DirectoryHasModuleMap[Dir] = false;
776 
777     // Keep track of all of the directories we checked, so we can mark them as
778     // having module maps if we eventually do find a module map.
779     FixUpDirectories.push_back(Dir);
780   } while (true);
781 
782   return false;
783 }
784 
785 StringRef HeaderSearch::findModuleForHeader(const FileEntry *File) {
786   if (ModuleMap::Module *Module = ModMap.findModuleForHeader(File))
787     return Module->getTopLevelModuleName();
788 
789   return StringRef();
790 }
791 
792 
793