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/FileManager.h"
16 #include "clang/Basic/IdentifierTable.h"
17 #include "clang/Lex/ExternalPreprocessorSource.h"
18 #include "clang/Lex/HeaderMap.h"
19 #include "clang/Lex/HeaderSearchOptions.h"
20 #include "clang/Lex/LexDiagnostic.h"
21 #include "clang/Lex/Lexer.h"
22 #include "clang/Lex/Preprocessor.h"
23 #include "llvm/ADT/APInt.h"
24 #include "llvm/ADT/Hashing.h"
25 #include "llvm/ADT/SmallString.h"
26 #include "llvm/Support/Capacity.h"
27 #include "llvm/Support/FileSystem.h"
28 #include "llvm/Support/Path.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include <cstdio>
31 #include <utility>
32 #if defined(LLVM_ON_UNIX)
33 #include <limits.h>
34 #endif
35 using namespace clang;
36
37 const IdentifierInfo *
getControllingMacro(ExternalPreprocessorSource * External)38 HeaderFileInfo::getControllingMacro(ExternalPreprocessorSource *External) {
39 if (ControllingMacro) {
40 if (ControllingMacro->isOutOfDate())
41 External->updateOutOfDateIdentifier(
42 *const_cast<IdentifierInfo *>(ControllingMacro));
43 return ControllingMacro;
44 }
45
46 if (!ControllingMacroID || !External)
47 return nullptr;
48
49 ControllingMacro = External->GetIdentifier(ControllingMacroID);
50 return ControllingMacro;
51 }
52
~ExternalHeaderFileInfoSource()53 ExternalHeaderFileInfoSource::~ExternalHeaderFileInfoSource() {}
54
HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts,SourceManager & SourceMgr,DiagnosticsEngine & Diags,const LangOptions & LangOpts,const TargetInfo * Target)55 HeaderSearch::HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts,
56 SourceManager &SourceMgr, DiagnosticsEngine &Diags,
57 const LangOptions &LangOpts,
58 const TargetInfo *Target)
59 : HSOpts(std::move(HSOpts)), Diags(Diags),
60 FileMgr(SourceMgr.getFileManager()), FrameworkMap(64),
61 ModMap(SourceMgr, Diags, LangOpts, Target, *this) {
62 AngledDirIdx = 0;
63 SystemDirIdx = 0;
64 NoCurDirSearch = false;
65
66 ExternalLookup = nullptr;
67 ExternalSource = nullptr;
68 NumIncluded = 0;
69 NumMultiIncludeFileOptzn = 0;
70 NumFrameworkLookups = NumSubFrameworkLookups = 0;
71 }
72
~HeaderSearch()73 HeaderSearch::~HeaderSearch() {
74 // Delete headermaps.
75 for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
76 delete HeaderMaps[i].second;
77 }
78
PrintStats()79 void HeaderSearch::PrintStats() {
80 fprintf(stderr, "\n*** HeaderSearch Stats:\n");
81 fprintf(stderr, "%d files tracked.\n", (int)FileInfo.size());
82 unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0;
83 for (unsigned i = 0, e = FileInfo.size(); i != e; ++i) {
84 NumOnceOnlyFiles += FileInfo[i].isImport;
85 if (MaxNumIncludes < FileInfo[i].NumIncludes)
86 MaxNumIncludes = FileInfo[i].NumIncludes;
87 NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1;
88 }
89 fprintf(stderr, " %d #import/#pragma once files.\n", NumOnceOnlyFiles);
90 fprintf(stderr, " %d included exactly once.\n", NumSingleIncludedFiles);
91 fprintf(stderr, " %d max times a file is included.\n", MaxNumIncludes);
92
93 fprintf(stderr, " %d #include/#include_next/#import.\n", NumIncluded);
94 fprintf(stderr, " %d #includes skipped due to"
95 " the multi-include optimization.\n", NumMultiIncludeFileOptzn);
96
97 fprintf(stderr, "%d framework lookups.\n", NumFrameworkLookups);
98 fprintf(stderr, "%d subframework lookups.\n", NumSubFrameworkLookups);
99 }
100
101 /// CreateHeaderMap - This method returns a HeaderMap for the specified
102 /// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
CreateHeaderMap(const FileEntry * FE)103 const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) {
104 // We expect the number of headermaps to be small, and almost always empty.
105 // If it ever grows, use of a linear search should be re-evaluated.
106 if (!HeaderMaps.empty()) {
107 for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
108 // Pointer equality comparison of FileEntries works because they are
109 // already uniqued by inode.
110 if (HeaderMaps[i].first == FE)
111 return HeaderMaps[i].second;
112 }
113
114 if (const HeaderMap *HM = HeaderMap::Create(FE, FileMgr)) {
115 HeaderMaps.push_back(std::make_pair(FE, HM));
116 return HM;
117 }
118
119 return nullptr;
120 }
121
getModuleFileName(Module * Module)122 std::string HeaderSearch::getModuleFileName(Module *Module) {
123 const FileEntry *ModuleMap =
124 getModuleMap().getModuleMapFileForUniquing(Module);
125 return getModuleFileName(Module->Name, ModuleMap->getName());
126 }
127
getModuleFileName(StringRef ModuleName,StringRef ModuleMapPath)128 std::string HeaderSearch::getModuleFileName(StringRef ModuleName,
129 StringRef ModuleMapPath) {
130 // If we don't have a module cache path or aren't supposed to use one, we
131 // can't do anything.
132 if (getModuleCachePath().empty())
133 return std::string();
134
135 SmallString<256> Result(getModuleCachePath());
136 llvm::sys::fs::make_absolute(Result);
137
138 if (HSOpts->DisableModuleHash) {
139 llvm::sys::path::append(Result, ModuleName + ".pcm");
140 } else {
141 // Construct the name <ModuleName>-<hash of ModuleMapPath>.pcm which should
142 // ideally be globally unique to this particular module. Name collisions
143 // in the hash are safe (because any translation unit can only import one
144 // module with each name), but result in a loss of caching.
145 //
146 // To avoid false-negatives, we form as canonical a path as we can, and map
147 // to lower-case in case we're on a case-insensitive file system.
148 auto *Dir =
149 FileMgr.getDirectory(llvm::sys::path::parent_path(ModuleMapPath));
150 if (!Dir)
151 return std::string();
152 auto DirName = FileMgr.getCanonicalName(Dir);
153 auto FileName = llvm::sys::path::filename(ModuleMapPath);
154
155 llvm::hash_code Hash =
156 llvm::hash_combine(DirName.lower(), FileName.lower());
157
158 SmallString<128> HashStr;
159 llvm::APInt(64, size_t(Hash)).toStringUnsigned(HashStr, /*Radix*/36);
160 llvm::sys::path::append(Result, ModuleName + "-" + HashStr + ".pcm");
161 }
162 return Result.str().str();
163 }
164
lookupModule(StringRef ModuleName,bool AllowSearch)165 Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) {
166 // Look in the module map to determine if there is a module by this name.
167 Module *Module = ModMap.findModule(ModuleName);
168 if (Module || !AllowSearch || !HSOpts->ImplicitModuleMaps)
169 return Module;
170
171 // Look through the various header search paths to load any available module
172 // maps, searching for a module map that describes this module.
173 for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
174 if (SearchDirs[Idx].isFramework()) {
175 // Search for or infer a module map for a framework.
176 SmallString<128> FrameworkDirName;
177 FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName();
178 llvm::sys::path::append(FrameworkDirName, ModuleName + ".framework");
179 if (const DirectoryEntry *FrameworkDir
180 = FileMgr.getDirectory(FrameworkDirName)) {
181 bool IsSystem
182 = SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User;
183 Module = loadFrameworkModule(ModuleName, FrameworkDir, IsSystem);
184 if (Module)
185 break;
186 }
187 }
188
189 // FIXME: Figure out how header maps and module maps will work together.
190
191 // Only deal with normal search directories.
192 if (!SearchDirs[Idx].isNormalDir())
193 continue;
194
195 bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
196 // Search for a module map file in this directory.
197 if (loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem,
198 /*IsFramework*/false) == LMM_NewlyLoaded) {
199 // We just loaded a module map file; check whether the module is
200 // available now.
201 Module = ModMap.findModule(ModuleName);
202 if (Module)
203 break;
204 }
205
206 // Search for a module map in a subdirectory with the same name as the
207 // module.
208 SmallString<128> NestedModuleMapDirName;
209 NestedModuleMapDirName = SearchDirs[Idx].getDir()->getName();
210 llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
211 if (loadModuleMapFile(NestedModuleMapDirName, IsSystem,
212 /*IsFramework*/false) == LMM_NewlyLoaded){
213 // If we just loaded a module map file, look for the module again.
214 Module = ModMap.findModule(ModuleName);
215 if (Module)
216 break;
217 }
218
219 // If we've already performed the exhaustive search for module maps in this
220 // search directory, don't do it again.
221 if (SearchDirs[Idx].haveSearchedAllModuleMaps())
222 continue;
223
224 // Load all module maps in the immediate subdirectories of this search
225 // directory.
226 loadSubdirectoryModuleMaps(SearchDirs[Idx]);
227
228 // Look again for the module.
229 Module = ModMap.findModule(ModuleName);
230 if (Module)
231 break;
232 }
233
234 return Module;
235 }
236
237 //===----------------------------------------------------------------------===//
238 // File lookup within a DirectoryLookup scope
239 //===----------------------------------------------------------------------===//
240
241 /// getName - Return the directory or filename corresponding to this lookup
242 /// object.
getName() const243 const char *DirectoryLookup::getName() const {
244 if (isNormalDir())
245 return getDir()->getName();
246 if (isFramework())
247 return getFrameworkDir()->getName();
248 assert(isHeaderMap() && "Unknown DirectoryLookup");
249 return getHeaderMap()->getFileName();
250 }
251
getFileAndSuggestModule(StringRef FileName,SourceLocation IncludeLoc,const DirectoryEntry * Dir,bool IsSystemHeaderDir,Module * RequestingModule,ModuleMap::KnownHeader * SuggestedModule)252 const FileEntry *HeaderSearch::getFileAndSuggestModule(
253 StringRef FileName, SourceLocation IncludeLoc, const DirectoryEntry *Dir,
254 bool IsSystemHeaderDir, Module *RequestingModule,
255 ModuleMap::KnownHeader *SuggestedModule) {
256 // If we have a module map that might map this header, load it and
257 // check whether we'll have a suggestion for a module.
258 const FileEntry *File = getFileMgr().getFile(FileName, /*OpenFile=*/true);
259 if (!File)
260 return nullptr;
261
262 // If there is a module that corresponds to this header, suggest it.
263 if (!findUsableModuleForHeader(File, Dir ? Dir : File->getDir(),
264 RequestingModule, SuggestedModule,
265 IsSystemHeaderDir))
266 return nullptr;
267
268 return File;
269 }
270
271 /// LookupFile - Lookup the specified file in this search path, returning it
272 /// if it exists or returning null if not.
LookupFile(StringRef & Filename,HeaderSearch & HS,SourceLocation IncludeLoc,SmallVectorImpl<char> * SearchPath,SmallVectorImpl<char> * RelativePath,Module * RequestingModule,ModuleMap::KnownHeader * SuggestedModule,bool & InUserSpecifiedSystemFramework,bool & HasBeenMapped,SmallVectorImpl<char> & MappedName) const273 const FileEntry *DirectoryLookup::LookupFile(
274 StringRef &Filename,
275 HeaderSearch &HS,
276 SourceLocation IncludeLoc,
277 SmallVectorImpl<char> *SearchPath,
278 SmallVectorImpl<char> *RelativePath,
279 Module *RequestingModule,
280 ModuleMap::KnownHeader *SuggestedModule,
281 bool &InUserSpecifiedSystemFramework,
282 bool &HasBeenMapped,
283 SmallVectorImpl<char> &MappedName) const {
284 InUserSpecifiedSystemFramework = false;
285 HasBeenMapped = false;
286
287 SmallString<1024> TmpDir;
288 if (isNormalDir()) {
289 // Concatenate the requested file onto the directory.
290 TmpDir = getDir()->getName();
291 llvm::sys::path::append(TmpDir, Filename);
292 if (SearchPath) {
293 StringRef SearchPathRef(getDir()->getName());
294 SearchPath->clear();
295 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
296 }
297 if (RelativePath) {
298 RelativePath->clear();
299 RelativePath->append(Filename.begin(), Filename.end());
300 }
301
302 return HS.getFileAndSuggestModule(TmpDir, IncludeLoc, getDir(),
303 isSystemHeaderDirectory(),
304 RequestingModule, SuggestedModule);
305 }
306
307 if (isFramework())
308 return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
309 RequestingModule, SuggestedModule,
310 InUserSpecifiedSystemFramework);
311
312 assert(isHeaderMap() && "Unknown directory lookup");
313 const HeaderMap *HM = getHeaderMap();
314 SmallString<1024> Path;
315 StringRef Dest = HM->lookupFilename(Filename, Path);
316 if (Dest.empty())
317 return nullptr;
318
319 const FileEntry *Result;
320
321 // Check if the headermap maps the filename to a framework include
322 // ("Foo.h" -> "Foo/Foo.h"), in which case continue header lookup using the
323 // framework include.
324 if (llvm::sys::path::is_relative(Dest)) {
325 MappedName.clear();
326 MappedName.append(Dest.begin(), Dest.end());
327 Filename = StringRef(MappedName.begin(), MappedName.size());
328 HasBeenMapped = true;
329 Result = HM->LookupFile(Filename, HS.getFileMgr());
330
331 } else {
332 Result = HS.getFileMgr().getFile(Dest);
333 }
334
335 if (Result) {
336 if (SearchPath) {
337 StringRef SearchPathRef(getName());
338 SearchPath->clear();
339 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
340 }
341 if (RelativePath) {
342 RelativePath->clear();
343 RelativePath->append(Filename.begin(), Filename.end());
344 }
345 }
346 return Result;
347 }
348
349 /// \brief Given a framework directory, find the top-most framework directory.
350 ///
351 /// \param FileMgr The file manager to use for directory lookups.
352 /// \param DirName The name of the framework directory.
353 /// \param SubmodulePath Will be populated with the submodule path from the
354 /// returned top-level module to the originally named framework.
355 static const DirectoryEntry *
getTopFrameworkDir(FileManager & FileMgr,StringRef DirName,SmallVectorImpl<std::string> & SubmodulePath)356 getTopFrameworkDir(FileManager &FileMgr, StringRef DirName,
357 SmallVectorImpl<std::string> &SubmodulePath) {
358 assert(llvm::sys::path::extension(DirName) == ".framework" &&
359 "Not a framework directory");
360
361 // Note: as an egregious but useful hack we use the real path here, because
362 // frameworks moving between top-level frameworks to embedded frameworks tend
363 // to be symlinked, and we base the logical structure of modules on the
364 // physical layout. In particular, we need to deal with crazy includes like
365 //
366 // #include <Foo/Frameworks/Bar.framework/Headers/Wibble.h>
367 //
368 // where 'Bar' used to be embedded in 'Foo', is now a top-level framework
369 // which one should access with, e.g.,
370 //
371 // #include <Bar/Wibble.h>
372 //
373 // Similar issues occur when a top-level framework has moved into an
374 // embedded framework.
375 const DirectoryEntry *TopFrameworkDir = FileMgr.getDirectory(DirName);
376 DirName = FileMgr.getCanonicalName(TopFrameworkDir);
377 do {
378 // Get the parent directory name.
379 DirName = llvm::sys::path::parent_path(DirName);
380 if (DirName.empty())
381 break;
382
383 // Determine whether this directory exists.
384 const DirectoryEntry *Dir = FileMgr.getDirectory(DirName);
385 if (!Dir)
386 break;
387
388 // If this is a framework directory, then we're a subframework of this
389 // framework.
390 if (llvm::sys::path::extension(DirName) == ".framework") {
391 SubmodulePath.push_back(llvm::sys::path::stem(DirName));
392 TopFrameworkDir = Dir;
393 }
394 } while (true);
395
396 return TopFrameworkDir;
397 }
398
399 /// DoFrameworkLookup - Do a lookup of the specified file in the current
400 /// DirectoryLookup, which is a framework directory.
DoFrameworkLookup(StringRef Filename,HeaderSearch & HS,SmallVectorImpl<char> * SearchPath,SmallVectorImpl<char> * RelativePath,Module * RequestingModule,ModuleMap::KnownHeader * SuggestedModule,bool & InUserSpecifiedSystemFramework) const401 const FileEntry *DirectoryLookup::DoFrameworkLookup(
402 StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath,
403 SmallVectorImpl<char> *RelativePath, Module *RequestingModule,
404 ModuleMap::KnownHeader *SuggestedModule,
405 bool &InUserSpecifiedSystemFramework) const {
406 FileManager &FileMgr = HS.getFileMgr();
407
408 // Framework names must have a '/' in the filename.
409 size_t SlashPos = Filename.find('/');
410 if (SlashPos == StringRef::npos) return nullptr;
411
412 // Find out if this is the home for the specified framework, by checking
413 // HeaderSearch. Possible answers are yes/no and unknown.
414 HeaderSearch::FrameworkCacheEntry &CacheEntry =
415 HS.LookupFrameworkCache(Filename.substr(0, SlashPos));
416
417 // If it is known and in some other directory, fail.
418 if (CacheEntry.Directory && CacheEntry.Directory != getFrameworkDir())
419 return nullptr;
420
421 // Otherwise, construct the path to this framework dir.
422
423 // FrameworkName = "/System/Library/Frameworks/"
424 SmallString<1024> FrameworkName;
425 FrameworkName += getFrameworkDir()->getName();
426 if (FrameworkName.empty() || FrameworkName.back() != '/')
427 FrameworkName.push_back('/');
428
429 // FrameworkName = "/System/Library/Frameworks/Cocoa"
430 StringRef ModuleName(Filename.begin(), SlashPos);
431 FrameworkName += ModuleName;
432
433 // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/"
434 FrameworkName += ".framework/";
435
436 // If the cache entry was unresolved, populate it now.
437 if (!CacheEntry.Directory) {
438 HS.IncrementFrameworkLookupCount();
439
440 // If the framework dir doesn't exist, we fail.
441 const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName);
442 if (!Dir) return nullptr;
443
444 // Otherwise, if it does, remember that this is the right direntry for this
445 // framework.
446 CacheEntry.Directory = getFrameworkDir();
447
448 // If this is a user search directory, check if the framework has been
449 // user-specified as a system framework.
450 if (getDirCharacteristic() == SrcMgr::C_User) {
451 SmallString<1024> SystemFrameworkMarker(FrameworkName);
452 SystemFrameworkMarker += ".system_framework";
453 if (llvm::sys::fs::exists(SystemFrameworkMarker)) {
454 CacheEntry.IsUserSpecifiedSystemFramework = true;
455 }
456 }
457 }
458
459 // Set the 'user-specified system framework' flag.
460 InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework;
461
462 if (RelativePath) {
463 RelativePath->clear();
464 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
465 }
466
467 // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h"
468 unsigned OrigSize = FrameworkName.size();
469
470 FrameworkName += "Headers/";
471
472 if (SearchPath) {
473 SearchPath->clear();
474 // Without trailing '/'.
475 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
476 }
477
478 FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
479 const FileEntry *FE = FileMgr.getFile(FrameworkName,
480 /*openFile=*/!SuggestedModule);
481 if (!FE) {
482 // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h"
483 const char *Private = "Private";
484 FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
485 Private+strlen(Private));
486 if (SearchPath)
487 SearchPath->insert(SearchPath->begin()+OrigSize, Private,
488 Private+strlen(Private));
489
490 FE = FileMgr.getFile(FrameworkName, /*openFile=*/!SuggestedModule);
491 }
492
493 // If we found the header and are allowed to suggest a module, do so now.
494 if (FE && SuggestedModule) {
495 // Find the framework in which this header occurs.
496 StringRef FrameworkPath = FE->getDir()->getName();
497 bool FoundFramework = false;
498 do {
499 // Determine whether this directory exists.
500 const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkPath);
501 if (!Dir)
502 break;
503
504 // If this is a framework directory, then we're a subframework of this
505 // framework.
506 if (llvm::sys::path::extension(FrameworkPath) == ".framework") {
507 FoundFramework = true;
508 break;
509 }
510
511 // Get the parent directory name.
512 FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
513 if (FrameworkPath.empty())
514 break;
515 } while (true);
516
517 bool IsSystem = getDirCharacteristic() != SrcMgr::C_User;
518 if (FoundFramework) {
519 if (!HS.findUsableModuleForFrameworkHeader(
520 FE, FrameworkPath, RequestingModule, SuggestedModule, IsSystem))
521 return nullptr;
522 } else {
523 if (!HS.findUsableModuleForHeader(FE, getDir(), RequestingModule,
524 SuggestedModule, IsSystem))
525 return nullptr;
526 }
527 }
528 return FE;
529 }
530
setTarget(const TargetInfo & Target)531 void HeaderSearch::setTarget(const TargetInfo &Target) {
532 ModMap.setTarget(Target);
533 }
534
535
536 //===----------------------------------------------------------------------===//
537 // Header File Location.
538 //===----------------------------------------------------------------------===//
539
540 /// \brief Return true with a diagnostic if the file that MSVC would have found
541 /// fails to match the one that Clang would have found with MSVC header search
542 /// disabled.
checkMSVCHeaderSearch(DiagnosticsEngine & Diags,const FileEntry * MSFE,const FileEntry * FE,SourceLocation IncludeLoc)543 static bool checkMSVCHeaderSearch(DiagnosticsEngine &Diags,
544 const FileEntry *MSFE, const FileEntry *FE,
545 SourceLocation IncludeLoc) {
546 if (MSFE && FE != MSFE) {
547 Diags.Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->getName();
548 return true;
549 }
550 return false;
551 }
552
copyString(StringRef Str,llvm::BumpPtrAllocator & Alloc)553 static const char *copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
554 assert(!Str.empty());
555 char *CopyStr = Alloc.Allocate<char>(Str.size()+1);
556 std::copy(Str.begin(), Str.end(), CopyStr);
557 CopyStr[Str.size()] = '\0';
558 return CopyStr;
559 }
560
561 /// LookupFile - Given a "foo" or \<foo> reference, look up the indicated file,
562 /// return null on failure. isAngled indicates whether the file reference is
563 /// for system \#include's or not (i.e. using <> instead of ""). Includers, if
564 /// non-empty, indicates where the \#including file(s) are, in case a relative
565 /// search is needed. Microsoft mode will pass all \#including files.
LookupFile(StringRef Filename,SourceLocation IncludeLoc,bool isAngled,const DirectoryLookup * FromDir,const DirectoryLookup * & CurDir,ArrayRef<std::pair<const FileEntry *,const DirectoryEntry * >> Includers,SmallVectorImpl<char> * SearchPath,SmallVectorImpl<char> * RelativePath,Module * RequestingModule,ModuleMap::KnownHeader * SuggestedModule,bool SkipCache,bool BuildSystemModule)566 const FileEntry *HeaderSearch::LookupFile(
567 StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
568 const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir,
569 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
570 SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
571 Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
572 bool SkipCache, bool BuildSystemModule) {
573 if (SuggestedModule)
574 *SuggestedModule = ModuleMap::KnownHeader();
575
576 // If 'Filename' is absolute, check to see if it exists and no searching.
577 if (llvm::sys::path::is_absolute(Filename)) {
578 CurDir = nullptr;
579
580 // If this was an #include_next "/absolute/file", fail.
581 if (FromDir) return nullptr;
582
583 if (SearchPath)
584 SearchPath->clear();
585 if (RelativePath) {
586 RelativePath->clear();
587 RelativePath->append(Filename.begin(), Filename.end());
588 }
589 // Otherwise, just return the file.
590 return getFileAndSuggestModule(Filename, IncludeLoc, nullptr,
591 /*IsSystemHeaderDir*/false,
592 RequestingModule, SuggestedModule);
593 }
594
595 // This is the header that MSVC's header search would have found.
596 const FileEntry *MSFE = nullptr;
597 ModuleMap::KnownHeader MSSuggestedModule;
598
599 // Unless disabled, check to see if the file is in the #includer's
600 // directory. This cannot be based on CurDir, because each includer could be
601 // a #include of a subdirectory (#include "foo/bar.h") and a subsequent
602 // include of "baz.h" should resolve to "whatever/foo/baz.h".
603 // This search is not done for <> headers.
604 if (!Includers.empty() && !isAngled && !NoCurDirSearch) {
605 SmallString<1024> TmpDir;
606 bool First = true;
607 for (const auto &IncluderAndDir : Includers) {
608 const FileEntry *Includer = IncluderAndDir.first;
609
610 // Concatenate the requested file onto the directory.
611 // FIXME: Portability. Filename concatenation should be in sys::Path.
612 TmpDir = IncluderAndDir.second->getName();
613 TmpDir.push_back('/');
614 TmpDir.append(Filename.begin(), Filename.end());
615
616 // FIXME: We don't cache the result of getFileInfo across the call to
617 // getFileAndSuggestModule, because it's a reference to an element of
618 // a container that could be reallocated across this call.
619 //
620 // If we have no includer, that means we're processing a #include
621 // from a module build. We should treat this as a system header if we're
622 // building a [system] module.
623 bool IncluderIsSystemHeader =
624 Includer ? getFileInfo(Includer).DirInfo != SrcMgr::C_User :
625 BuildSystemModule;
626 if (const FileEntry *FE = getFileAndSuggestModule(
627 TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
628 RequestingModule, SuggestedModule)) {
629 if (!Includer) {
630 assert(First && "only first includer can have no file");
631 return FE;
632 }
633
634 // Leave CurDir unset.
635 // This file is a system header or C++ unfriendly if the old file is.
636 //
637 // Note that we only use one of FromHFI/ToHFI at once, due to potential
638 // reallocation of the underlying vector potentially making the first
639 // reference binding dangling.
640 HeaderFileInfo &FromHFI = getFileInfo(Includer);
641 unsigned DirInfo = FromHFI.DirInfo;
642 bool IndexHeaderMapHeader = FromHFI.IndexHeaderMapHeader;
643 StringRef Framework = FromHFI.Framework;
644
645 HeaderFileInfo &ToHFI = getFileInfo(FE);
646 ToHFI.DirInfo = DirInfo;
647 ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader;
648 ToHFI.Framework = Framework;
649
650 if (SearchPath) {
651 StringRef SearchPathRef(IncluderAndDir.second->getName());
652 SearchPath->clear();
653 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
654 }
655 if (RelativePath) {
656 RelativePath->clear();
657 RelativePath->append(Filename.begin(), Filename.end());
658 }
659 if (First)
660 return FE;
661
662 // Otherwise, we found the path via MSVC header search rules. If
663 // -Wmsvc-include is enabled, we have to keep searching to see if we
664 // would've found this header in -I or -isystem directories.
665 if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
666 return FE;
667 } else {
668 MSFE = FE;
669 if (SuggestedModule) {
670 MSSuggestedModule = *SuggestedModule;
671 *SuggestedModule = ModuleMap::KnownHeader();
672 }
673 break;
674 }
675 }
676 First = false;
677 }
678 }
679
680 CurDir = nullptr;
681
682 // If this is a system #include, ignore the user #include locs.
683 unsigned i = isAngled ? AngledDirIdx : 0;
684
685 // If this is a #include_next request, start searching after the directory the
686 // file was found in.
687 if (FromDir)
688 i = FromDir-&SearchDirs[0];
689
690 // Cache all of the lookups performed by this method. Many headers are
691 // multiply included, and the "pragma once" optimization prevents them from
692 // being relex/pp'd, but they would still have to search through a
693 // (potentially huge) series of SearchDirs to find it.
694 LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename];
695
696 // If the entry has been previously looked up, the first value will be
697 // non-zero. If the value is equal to i (the start point of our search), then
698 // this is a matching hit.
699 if (!SkipCache && CacheLookup.StartIdx == i+1) {
700 // Skip querying potentially lots of directories for this lookup.
701 i = CacheLookup.HitIdx;
702 if (CacheLookup.MappedName)
703 Filename = CacheLookup.MappedName;
704 } else {
705 // Otherwise, this is the first query, or the previous query didn't match
706 // our search start. We will fill in our found location below, so prime the
707 // start point value.
708 CacheLookup.reset(/*StartIdx=*/i+1);
709 }
710
711 SmallString<64> MappedName;
712
713 // Check each directory in sequence to see if it contains this file.
714 for (; i != SearchDirs.size(); ++i) {
715 bool InUserSpecifiedSystemFramework = false;
716 bool HasBeenMapped = false;
717 const FileEntry *FE = SearchDirs[i].LookupFile(
718 Filename, *this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
719 SuggestedModule, InUserSpecifiedSystemFramework, HasBeenMapped,
720 MappedName);
721 if (HasBeenMapped) {
722 CacheLookup.MappedName =
723 copyString(Filename, LookupFileCache.getAllocator());
724 }
725 if (!FE) continue;
726
727 CurDir = &SearchDirs[i];
728
729 // This file is a system header or C++ unfriendly if the dir is.
730 HeaderFileInfo &HFI = getFileInfo(FE);
731 HFI.DirInfo = CurDir->getDirCharacteristic();
732
733 // If the directory characteristic is User but this framework was
734 // user-specified to be treated as a system framework, promote the
735 // characteristic.
736 if (HFI.DirInfo == SrcMgr::C_User && InUserSpecifiedSystemFramework)
737 HFI.DirInfo = SrcMgr::C_System;
738
739 // If the filename matches a known system header prefix, override
740 // whether the file is a system header.
741 for (unsigned j = SystemHeaderPrefixes.size(); j; --j) {
742 if (Filename.startswith(SystemHeaderPrefixes[j-1].first)) {
743 HFI.DirInfo = SystemHeaderPrefixes[j-1].second ? SrcMgr::C_System
744 : SrcMgr::C_User;
745 break;
746 }
747 }
748
749 // If this file is found in a header map and uses the framework style of
750 // includes, then this header is part of a framework we're building.
751 if (CurDir->isIndexHeaderMap()) {
752 size_t SlashPos = Filename.find('/');
753 if (SlashPos != StringRef::npos) {
754 HFI.IndexHeaderMapHeader = 1;
755 HFI.Framework = getUniqueFrameworkName(StringRef(Filename.begin(),
756 SlashPos));
757 }
758 }
759
760 if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) {
761 if (SuggestedModule)
762 *SuggestedModule = MSSuggestedModule;
763 return MSFE;
764 }
765
766 // Remember this location for the next lookup we do.
767 CacheLookup.HitIdx = i;
768 return FE;
769 }
770
771 // If we are including a file with a quoted include "foo.h" from inside
772 // a header in a framework that is currently being built, and we couldn't
773 // resolve "foo.h" any other way, change the include to <Foo/foo.h>, where
774 // "Foo" is the name of the framework in which the including header was found.
775 if (!Includers.empty() && Includers.front().first && !isAngled &&
776 Filename.find('/') == StringRef::npos) {
777 HeaderFileInfo &IncludingHFI = getFileInfo(Includers.front().first);
778 if (IncludingHFI.IndexHeaderMapHeader) {
779 SmallString<128> ScratchFilename;
780 ScratchFilename += IncludingHFI.Framework;
781 ScratchFilename += '/';
782 ScratchFilename += Filename;
783
784 const FileEntry *FE =
785 LookupFile(ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir,
786 CurDir, Includers.front(), SearchPath, RelativePath,
787 RequestingModule, SuggestedModule);
788
789 if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) {
790 if (SuggestedModule)
791 *SuggestedModule = MSSuggestedModule;
792 return MSFE;
793 }
794
795 LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename];
796 CacheLookup.HitIdx = LookupFileCache[ScratchFilename].HitIdx;
797 // FIXME: SuggestedModule.
798 return FE;
799 }
800 }
801
802 if (checkMSVCHeaderSearch(Diags, MSFE, nullptr, IncludeLoc)) {
803 if (SuggestedModule)
804 *SuggestedModule = MSSuggestedModule;
805 return MSFE;
806 }
807
808 // Otherwise, didn't find it. Remember we didn't find this.
809 CacheLookup.HitIdx = SearchDirs.size();
810 return nullptr;
811 }
812
813 /// LookupSubframeworkHeader - Look up a subframework for the specified
814 /// \#include file. For example, if \#include'ing <HIToolbox/HIToolbox.h> from
815 /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
816 /// is a subframework within Carbon.framework. If so, return the FileEntry
817 /// for the designated file, otherwise return null.
818 const FileEntry *HeaderSearch::
LookupSubframeworkHeader(StringRef Filename,const FileEntry * ContextFileEnt,SmallVectorImpl<char> * SearchPath,SmallVectorImpl<char> * RelativePath,Module * RequestingModule,ModuleMap::KnownHeader * SuggestedModule)819 LookupSubframeworkHeader(StringRef Filename,
820 const FileEntry *ContextFileEnt,
821 SmallVectorImpl<char> *SearchPath,
822 SmallVectorImpl<char> *RelativePath,
823 Module *RequestingModule,
824 ModuleMap::KnownHeader *SuggestedModule) {
825 assert(ContextFileEnt && "No context file?");
826
827 // Framework names must have a '/' in the filename. Find it.
828 // FIXME: Should we permit '\' on Windows?
829 size_t SlashPos = Filename.find('/');
830 if (SlashPos == StringRef::npos) return nullptr;
831
832 // Look up the base framework name of the ContextFileEnt.
833 const char *ContextName = ContextFileEnt->getName();
834
835 // If the context info wasn't a framework, couldn't be a subframework.
836 const unsigned DotFrameworkLen = 10;
837 const char *FrameworkPos = strstr(ContextName, ".framework");
838 if (FrameworkPos == nullptr ||
839 (FrameworkPos[DotFrameworkLen] != '/' &&
840 FrameworkPos[DotFrameworkLen] != '\\'))
841 return nullptr;
842
843 SmallString<1024> FrameworkName(ContextName, FrameworkPos+DotFrameworkLen+1);
844
845 // Append Frameworks/HIToolbox.framework/
846 FrameworkName += "Frameworks/";
847 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
848 FrameworkName += ".framework/";
849
850 auto &CacheLookup =
851 *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos),
852 FrameworkCacheEntry())).first;
853
854 // Some other location?
855 if (CacheLookup.second.Directory &&
856 CacheLookup.first().size() == FrameworkName.size() &&
857 memcmp(CacheLookup.first().data(), &FrameworkName[0],
858 CacheLookup.first().size()) != 0)
859 return nullptr;
860
861 // Cache subframework.
862 if (!CacheLookup.second.Directory) {
863 ++NumSubFrameworkLookups;
864
865 // If the framework dir doesn't exist, we fail.
866 const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName);
867 if (!Dir) return nullptr;
868
869 // Otherwise, if it does, remember that this is the right direntry for this
870 // framework.
871 CacheLookup.second.Directory = Dir;
872 }
873
874 const FileEntry *FE = nullptr;
875
876 if (RelativePath) {
877 RelativePath->clear();
878 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
879 }
880
881 // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h"
882 SmallString<1024> HeadersFilename(FrameworkName);
883 HeadersFilename += "Headers/";
884 if (SearchPath) {
885 SearchPath->clear();
886 // Without trailing '/'.
887 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
888 }
889
890 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
891 if (!(FE = FileMgr.getFile(HeadersFilename, /*openFile=*/true))) {
892
893 // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h"
894 HeadersFilename = FrameworkName;
895 HeadersFilename += "PrivateHeaders/";
896 if (SearchPath) {
897 SearchPath->clear();
898 // Without trailing '/'.
899 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
900 }
901
902 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
903 if (!(FE = FileMgr.getFile(HeadersFilename, /*openFile=*/true)))
904 return nullptr;
905 }
906
907 // This file is a system header or C++ unfriendly if the old file is.
908 //
909 // Note that the temporary 'DirInfo' is required here, as either call to
910 // getFileInfo could resize the vector and we don't want to rely on order
911 // of evaluation.
912 unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo;
913 getFileInfo(FE).DirInfo = DirInfo;
914
915 FrameworkName.pop_back(); // remove the trailing '/'
916 if (!findUsableModuleForFrameworkHeader(FE, FrameworkName, RequestingModule,
917 SuggestedModule, /*IsSystem*/ false))
918 return nullptr;
919
920 return FE;
921 }
922
923 //===----------------------------------------------------------------------===//
924 // File Info Management.
925 //===----------------------------------------------------------------------===//
926
927 /// \brief Merge the header file info provided by \p OtherHFI into the current
928 /// header file info (\p HFI)
mergeHeaderFileInfo(HeaderFileInfo & HFI,const HeaderFileInfo & OtherHFI)929 static void mergeHeaderFileInfo(HeaderFileInfo &HFI,
930 const HeaderFileInfo &OtherHFI) {
931 assert(OtherHFI.External && "expected to merge external HFI");
932
933 HFI.isImport |= OtherHFI.isImport;
934 HFI.isPragmaOnce |= OtherHFI.isPragmaOnce;
935 HFI.isModuleHeader |= OtherHFI.isModuleHeader;
936 HFI.NumIncludes += OtherHFI.NumIncludes;
937
938 if (!HFI.ControllingMacro && !HFI.ControllingMacroID) {
939 HFI.ControllingMacro = OtherHFI.ControllingMacro;
940 HFI.ControllingMacroID = OtherHFI.ControllingMacroID;
941 }
942
943 HFI.DirInfo = OtherHFI.DirInfo;
944 HFI.External = (!HFI.IsValid || HFI.External);
945 HFI.IsValid = true;
946 HFI.IndexHeaderMapHeader = OtherHFI.IndexHeaderMapHeader;
947
948 if (HFI.Framework.empty())
949 HFI.Framework = OtherHFI.Framework;
950 }
951
952 /// getFileInfo - Return the HeaderFileInfo structure for the specified
953 /// FileEntry.
getFileInfo(const FileEntry * FE)954 HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) {
955 if (FE->getUID() >= FileInfo.size())
956 FileInfo.resize(FE->getUID() + 1);
957
958 HeaderFileInfo *HFI = &FileInfo[FE->getUID()];
959 // FIXME: Use a generation count to check whether this is really up to date.
960 if (ExternalSource && !HFI->Resolved) {
961 HFI->Resolved = true;
962 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
963
964 HFI = &FileInfo[FE->getUID()];
965 if (ExternalHFI.External)
966 mergeHeaderFileInfo(*HFI, ExternalHFI);
967 }
968
969 HFI->IsValid = true;
970 // We have local information about this header file, so it's no longer
971 // strictly external.
972 HFI->External = false;
973 return *HFI;
974 }
975
976 const HeaderFileInfo *
getExistingFileInfo(const FileEntry * FE,bool WantExternal) const977 HeaderSearch::getExistingFileInfo(const FileEntry *FE,
978 bool WantExternal) const {
979 // If we have an external source, ensure we have the latest information.
980 // FIXME: Use a generation count to check whether this is really up to date.
981 HeaderFileInfo *HFI;
982 if (ExternalSource) {
983 if (FE->getUID() >= FileInfo.size()) {
984 if (!WantExternal)
985 return nullptr;
986 FileInfo.resize(FE->getUID() + 1);
987 }
988
989 HFI = &FileInfo[FE->getUID()];
990 if (!WantExternal && (!HFI->IsValid || HFI->External))
991 return nullptr;
992 if (!HFI->Resolved) {
993 HFI->Resolved = true;
994 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
995
996 HFI = &FileInfo[FE->getUID()];
997 if (ExternalHFI.External)
998 mergeHeaderFileInfo(*HFI, ExternalHFI);
999 }
1000 } else if (FE->getUID() >= FileInfo.size()) {
1001 return nullptr;
1002 } else {
1003 HFI = &FileInfo[FE->getUID()];
1004 }
1005
1006 if (!HFI->IsValid || (HFI->External && !WantExternal))
1007 return nullptr;
1008
1009 return HFI;
1010 }
1011
isFileMultipleIncludeGuarded(const FileEntry * File)1012 bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) {
1013 // Check if we've ever seen this file as a header.
1014 if (auto *HFI = getExistingFileInfo(File))
1015 return HFI->isPragmaOnce || HFI->isImport || HFI->ControllingMacro ||
1016 HFI->ControllingMacroID;
1017 return false;
1018 }
1019
MarkFileModuleHeader(const FileEntry * FE,ModuleMap::ModuleHeaderRole Role,bool isCompilingModuleHeader)1020 void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE,
1021 ModuleMap::ModuleHeaderRole Role,
1022 bool isCompilingModuleHeader) {
1023 bool isModularHeader = !(Role & ModuleMap::TextualHeader);
1024
1025 // Don't mark the file info as non-external if there's nothing to change.
1026 if (!isCompilingModuleHeader) {
1027 if (!isModularHeader)
1028 return;
1029 auto *HFI = getExistingFileInfo(FE);
1030 if (HFI && HFI->isModuleHeader)
1031 return;
1032 }
1033
1034 auto &HFI = getFileInfo(FE);
1035 HFI.isModuleHeader |= isModularHeader;
1036 HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1037 }
1038
ShouldEnterIncludeFile(Preprocessor & PP,const FileEntry * File,bool isImport,Module * M)1039 bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
1040 const FileEntry *File,
1041 bool isImport, Module *M) {
1042 ++NumIncluded; // Count # of attempted #includes.
1043
1044 // Get information about this file.
1045 HeaderFileInfo &FileInfo = getFileInfo(File);
1046
1047 // If this is a #import directive, check that we have not already imported
1048 // this header.
1049 if (isImport) {
1050 // If this has already been imported, don't import it again.
1051 FileInfo.isImport = true;
1052
1053 // Has this already been #import'ed or #include'd?
1054 if (FileInfo.NumIncludes) return false;
1055 } else {
1056 // Otherwise, if this is a #include of a file that was previously #import'd
1057 // or if this is the second #include of a #pragma once file, ignore it.
1058 if (FileInfo.isImport)
1059 return false;
1060 }
1061
1062 // Next, check to see if the file is wrapped with #ifndef guards. If so, and
1063 // if the macro that guards it is defined, we know the #include has no effect.
1064 if (const IdentifierInfo *ControllingMacro
1065 = FileInfo.getControllingMacro(ExternalLookup)) {
1066 // If the header corresponds to a module, check whether the macro is already
1067 // defined in that module rather than checking in the current set of visible
1068 // modules.
1069 if (M ? PP.isMacroDefinedInLocalModule(ControllingMacro, M)
1070 : PP.isMacroDefined(ControllingMacro)) {
1071 ++NumMultiIncludeFileOptzn;
1072 return false;
1073 }
1074 }
1075
1076 // Increment the number of times this file has been included.
1077 ++FileInfo.NumIncludes;
1078
1079 return true;
1080 }
1081
getTotalMemory() const1082 size_t HeaderSearch::getTotalMemory() const {
1083 return SearchDirs.capacity()
1084 + llvm::capacity_in_bytes(FileInfo)
1085 + llvm::capacity_in_bytes(HeaderMaps)
1086 + LookupFileCache.getAllocator().getTotalMemory()
1087 + FrameworkMap.getAllocator().getTotalMemory();
1088 }
1089
getUniqueFrameworkName(StringRef Framework)1090 StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) {
1091 return FrameworkNames.insert(Framework).first->first();
1092 }
1093
hasModuleMap(StringRef FileName,const DirectoryEntry * Root,bool IsSystem)1094 bool HeaderSearch::hasModuleMap(StringRef FileName,
1095 const DirectoryEntry *Root,
1096 bool IsSystem) {
1097 if (!HSOpts->ImplicitModuleMaps)
1098 return false;
1099
1100 SmallVector<const DirectoryEntry *, 2> FixUpDirectories;
1101
1102 StringRef DirName = FileName;
1103 do {
1104 // Get the parent directory name.
1105 DirName = llvm::sys::path::parent_path(DirName);
1106 if (DirName.empty())
1107 return false;
1108
1109 // Determine whether this directory exists.
1110 const DirectoryEntry *Dir = FileMgr.getDirectory(DirName);
1111 if (!Dir)
1112 return false;
1113
1114 // Try to load the module map file in this directory.
1115 switch (loadModuleMapFile(Dir, IsSystem,
1116 llvm::sys::path::extension(Dir->getName()) ==
1117 ".framework")) {
1118 case LMM_NewlyLoaded:
1119 case LMM_AlreadyLoaded:
1120 // Success. All of the directories we stepped through inherit this module
1121 // map file.
1122 for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
1123 DirectoryHasModuleMap[FixUpDirectories[I]] = true;
1124 return true;
1125
1126 case LMM_NoDirectory:
1127 case LMM_InvalidModuleMap:
1128 break;
1129 }
1130
1131 // If we hit the top of our search, we're done.
1132 if (Dir == Root)
1133 return false;
1134
1135 // Keep track of all of the directories we checked, so we can mark them as
1136 // having module maps if we eventually do find a module map.
1137 FixUpDirectories.push_back(Dir);
1138 } while (true);
1139 }
1140
1141 ModuleMap::KnownHeader
findModuleForHeader(const FileEntry * File) const1142 HeaderSearch::findModuleForHeader(const FileEntry *File) const {
1143 if (ExternalSource) {
1144 // Make sure the external source has handled header info about this file,
1145 // which includes whether the file is part of a module.
1146 (void)getExistingFileInfo(File);
1147 }
1148 return ModMap.findModuleForHeader(File);
1149 }
1150
findUsableModuleForHeader(const FileEntry * File,const DirectoryEntry * Root,Module * RequestingModule,ModuleMap::KnownHeader * SuggestedModule,bool IsSystemHeaderDir)1151 bool HeaderSearch::findUsableModuleForHeader(
1152 const FileEntry *File, const DirectoryEntry *Root, Module *RequestingModule,
1153 ModuleMap::KnownHeader *SuggestedModule, bool IsSystemHeaderDir) {
1154 if (File && SuggestedModule) {
1155 // If there is a module that corresponds to this header, suggest it.
1156 hasModuleMap(File->getName(), Root, IsSystemHeaderDir);
1157 *SuggestedModule = findModuleForHeader(File);
1158 }
1159 return true;
1160 }
1161
findUsableModuleForFrameworkHeader(const FileEntry * File,StringRef FrameworkName,Module * RequestingModule,ModuleMap::KnownHeader * SuggestedModule,bool IsSystemFramework)1162 bool HeaderSearch::findUsableModuleForFrameworkHeader(
1163 const FileEntry *File, StringRef FrameworkName, Module *RequestingModule,
1164 ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework) {
1165 // If we're supposed to suggest a module, look for one now.
1166 if (SuggestedModule) {
1167 // Find the top-level framework based on this framework.
1168 SmallVector<std::string, 4> SubmodulePath;
1169 const DirectoryEntry *TopFrameworkDir
1170 = ::getTopFrameworkDir(FileMgr, FrameworkName, SubmodulePath);
1171
1172 // Determine the name of the top-level framework.
1173 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName());
1174
1175 // Load this framework module. If that succeeds, find the suggested module
1176 // for this header, if any.
1177 loadFrameworkModule(ModuleName, TopFrameworkDir, IsSystemFramework);
1178
1179 // FIXME: This can find a module not part of ModuleName, which is
1180 // important so that we're consistent about whether this header
1181 // corresponds to a module. Possibly we should lock down framework modules
1182 // so that this is not possible.
1183 *SuggestedModule = findModuleForHeader(File);
1184 }
1185 return true;
1186 }
1187
getPrivateModuleMap(const FileEntry * File,FileManager & FileMgr)1188 static const FileEntry *getPrivateModuleMap(const FileEntry *File,
1189 FileManager &FileMgr) {
1190 StringRef Filename = llvm::sys::path::filename(File->getName());
1191 SmallString<128> PrivateFilename(File->getDir()->getName());
1192 if (Filename == "module.map")
1193 llvm::sys::path::append(PrivateFilename, "module_private.map");
1194 else if (Filename == "module.modulemap")
1195 llvm::sys::path::append(PrivateFilename, "module.private.modulemap");
1196 else
1197 return nullptr;
1198 return FileMgr.getFile(PrivateFilename);
1199 }
1200
loadModuleMapFile(const FileEntry * File,bool IsSystem)1201 bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem) {
1202 // Find the directory for the module. For frameworks, that may require going
1203 // up from the 'Modules' directory.
1204 const DirectoryEntry *Dir = nullptr;
1205 if (getHeaderSearchOpts().ModuleMapFileHomeIsCwd)
1206 Dir = FileMgr.getDirectory(".");
1207 else {
1208 Dir = File->getDir();
1209 StringRef DirName(Dir->getName());
1210 if (llvm::sys::path::filename(DirName) == "Modules") {
1211 DirName = llvm::sys::path::parent_path(DirName);
1212 if (DirName.endswith(".framework"))
1213 Dir = FileMgr.getDirectory(DirName);
1214 // FIXME: This assert can fail if there's a race between the above check
1215 // and the removal of the directory.
1216 assert(Dir && "parent must exist");
1217 }
1218 }
1219
1220 switch (loadModuleMapFileImpl(File, IsSystem, Dir)) {
1221 case LMM_AlreadyLoaded:
1222 case LMM_NewlyLoaded:
1223 return false;
1224 case LMM_NoDirectory:
1225 case LMM_InvalidModuleMap:
1226 return true;
1227 }
1228 llvm_unreachable("Unknown load module map result");
1229 }
1230
1231 HeaderSearch::LoadModuleMapResult
loadModuleMapFileImpl(const FileEntry * File,bool IsSystem,const DirectoryEntry * Dir)1232 HeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem,
1233 const DirectoryEntry *Dir) {
1234 assert(File && "expected FileEntry");
1235
1236 // Check whether we've already loaded this module map, and mark it as being
1237 // loaded in case we recursively try to load it from itself.
1238 auto AddResult = LoadedModuleMaps.insert(std::make_pair(File, true));
1239 if (!AddResult.second)
1240 return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1241
1242 if (ModMap.parseModuleMapFile(File, IsSystem, Dir)) {
1243 LoadedModuleMaps[File] = false;
1244 return LMM_InvalidModuleMap;
1245 }
1246
1247 // Try to load a corresponding private module map.
1248 if (const FileEntry *PMMFile = getPrivateModuleMap(File, FileMgr)) {
1249 if (ModMap.parseModuleMapFile(PMMFile, IsSystem, Dir)) {
1250 LoadedModuleMaps[File] = false;
1251 return LMM_InvalidModuleMap;
1252 }
1253 }
1254
1255 // This directory has a module map.
1256 return LMM_NewlyLoaded;
1257 }
1258
1259 const FileEntry *
lookupModuleMapFile(const DirectoryEntry * Dir,bool IsFramework)1260 HeaderSearch::lookupModuleMapFile(const DirectoryEntry *Dir, bool IsFramework) {
1261 if (!HSOpts->ImplicitModuleMaps)
1262 return nullptr;
1263 // For frameworks, the preferred spelling is Modules/module.modulemap, but
1264 // module.map at the framework root is also accepted.
1265 SmallString<128> ModuleMapFileName(Dir->getName());
1266 if (IsFramework)
1267 llvm::sys::path::append(ModuleMapFileName, "Modules");
1268 llvm::sys::path::append(ModuleMapFileName, "module.modulemap");
1269 if (const FileEntry *F = FileMgr.getFile(ModuleMapFileName))
1270 return F;
1271
1272 // Continue to allow module.map
1273 ModuleMapFileName = Dir->getName();
1274 llvm::sys::path::append(ModuleMapFileName, "module.map");
1275 return FileMgr.getFile(ModuleMapFileName);
1276 }
1277
loadFrameworkModule(StringRef Name,const DirectoryEntry * Dir,bool IsSystem)1278 Module *HeaderSearch::loadFrameworkModule(StringRef Name,
1279 const DirectoryEntry *Dir,
1280 bool IsSystem) {
1281 if (Module *Module = ModMap.findModule(Name))
1282 return Module;
1283
1284 // Try to load a module map file.
1285 switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/true)) {
1286 case LMM_InvalidModuleMap:
1287 // Try to infer a module map from the framework directory.
1288 if (HSOpts->ImplicitModuleMaps)
1289 ModMap.inferFrameworkModule(Dir, IsSystem, /*Parent=*/nullptr);
1290 break;
1291
1292 case LMM_AlreadyLoaded:
1293 case LMM_NoDirectory:
1294 return nullptr;
1295
1296 case LMM_NewlyLoaded:
1297 break;
1298 }
1299
1300 return ModMap.findModule(Name);
1301 }
1302
1303
1304 HeaderSearch::LoadModuleMapResult
loadModuleMapFile(StringRef DirName,bool IsSystem,bool IsFramework)1305 HeaderSearch::loadModuleMapFile(StringRef DirName, bool IsSystem,
1306 bool IsFramework) {
1307 if (const DirectoryEntry *Dir = FileMgr.getDirectory(DirName))
1308 return loadModuleMapFile(Dir, IsSystem, IsFramework);
1309
1310 return LMM_NoDirectory;
1311 }
1312
1313 HeaderSearch::LoadModuleMapResult
loadModuleMapFile(const DirectoryEntry * Dir,bool IsSystem,bool IsFramework)1314 HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir, bool IsSystem,
1315 bool IsFramework) {
1316 auto KnownDir = DirectoryHasModuleMap.find(Dir);
1317 if (KnownDir != DirectoryHasModuleMap.end())
1318 return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1319
1320 if (const FileEntry *ModuleMapFile = lookupModuleMapFile(Dir, IsFramework)) {
1321 LoadModuleMapResult Result =
1322 loadModuleMapFileImpl(ModuleMapFile, IsSystem, Dir);
1323 // Add Dir explicitly in case ModuleMapFile is in a subdirectory.
1324 // E.g. Foo.framework/Modules/module.modulemap
1325 // ^Dir ^ModuleMapFile
1326 if (Result == LMM_NewlyLoaded)
1327 DirectoryHasModuleMap[Dir] = true;
1328 else if (Result == LMM_InvalidModuleMap)
1329 DirectoryHasModuleMap[Dir] = false;
1330 return Result;
1331 }
1332 return LMM_InvalidModuleMap;
1333 }
1334
collectAllModules(SmallVectorImpl<Module * > & Modules)1335 void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) {
1336 Modules.clear();
1337
1338 if (HSOpts->ImplicitModuleMaps) {
1339 // Load module maps for each of the header search directories.
1340 for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
1341 bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
1342 if (SearchDirs[Idx].isFramework()) {
1343 std::error_code EC;
1344 SmallString<128> DirNative;
1345 llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(),
1346 DirNative);
1347
1348 // Search each of the ".framework" directories to load them as modules.
1349 vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
1350 for (vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
1351 Dir != DirEnd && !EC; Dir.increment(EC)) {
1352 if (llvm::sys::path::extension(Dir->getName()) != ".framework")
1353 continue;
1354
1355 const DirectoryEntry *FrameworkDir =
1356 FileMgr.getDirectory(Dir->getName());
1357 if (!FrameworkDir)
1358 continue;
1359
1360 // Load this framework module.
1361 loadFrameworkModule(llvm::sys::path::stem(Dir->getName()),
1362 FrameworkDir, IsSystem);
1363 }
1364 continue;
1365 }
1366
1367 // FIXME: Deal with header maps.
1368 if (SearchDirs[Idx].isHeaderMap())
1369 continue;
1370
1371 // Try to load a module map file for the search directory.
1372 loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem,
1373 /*IsFramework*/ false);
1374
1375 // Try to load module map files for immediate subdirectories of this
1376 // search directory.
1377 loadSubdirectoryModuleMaps(SearchDirs[Idx]);
1378 }
1379 }
1380
1381 // Populate the list of modules.
1382 for (ModuleMap::module_iterator M = ModMap.module_begin(),
1383 MEnd = ModMap.module_end();
1384 M != MEnd; ++M) {
1385 Modules.push_back(M->getValue());
1386 }
1387 }
1388
loadTopLevelSystemModules()1389 void HeaderSearch::loadTopLevelSystemModules() {
1390 if (!HSOpts->ImplicitModuleMaps)
1391 return;
1392
1393 // Load module maps for each of the header search directories.
1394 for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
1395 // We only care about normal header directories.
1396 if (!SearchDirs[Idx].isNormalDir()) {
1397 continue;
1398 }
1399
1400 // Try to load a module map file for the search directory.
1401 loadModuleMapFile(SearchDirs[Idx].getDir(),
1402 SearchDirs[Idx].isSystemHeaderDirectory(),
1403 SearchDirs[Idx].isFramework());
1404 }
1405 }
1406
loadSubdirectoryModuleMaps(DirectoryLookup & SearchDir)1407 void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) {
1408 assert(HSOpts->ImplicitModuleMaps &&
1409 "Should not be loading subdirectory module maps");
1410
1411 if (SearchDir.haveSearchedAllModuleMaps())
1412 return;
1413
1414 std::error_code EC;
1415 SmallString<128> DirNative;
1416 llvm::sys::path::native(SearchDir.getDir()->getName(), DirNative);
1417 vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
1418 for (vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
1419 Dir != DirEnd && !EC; Dir.increment(EC)) {
1420 bool IsFramework =
1421 llvm::sys::path::extension(Dir->getName()) == ".framework";
1422 if (IsFramework == SearchDir.isFramework())
1423 loadModuleMapFile(Dir->getName(), SearchDir.isSystemHeaderDirectory(),
1424 SearchDir.isFramework());
1425 }
1426
1427 SearchDir.setSearchedAllModuleMaps(true);
1428 }
1429
suggestPathToFileForDiagnostics(const FileEntry * File,bool * IsSystem)1430 std::string HeaderSearch::suggestPathToFileForDiagnostics(const FileEntry *File,
1431 bool *IsSystem) {
1432 // FIXME: We assume that the path name currently cached in the FileEntry is
1433 // the most appropriate one for this analysis (and that it's spelled the same
1434 // way as the corresponding header search path).
1435 const char *Name = File->getName();
1436
1437 unsigned BestPrefixLength = 0;
1438 unsigned BestSearchDir;
1439
1440 for (unsigned I = 0; I != SearchDirs.size(); ++I) {
1441 // FIXME: Support this search within frameworks and header maps.
1442 if (!SearchDirs[I].isNormalDir())
1443 continue;
1444
1445 const char *Dir = SearchDirs[I].getDir()->getName();
1446 for (auto NI = llvm::sys::path::begin(Name),
1447 NE = llvm::sys::path::end(Name),
1448 DI = llvm::sys::path::begin(Dir),
1449 DE = llvm::sys::path::end(Dir);
1450 /*termination condition in loop*/; ++NI, ++DI) {
1451 // '.' components in Name are ignored.
1452 while (NI != NE && *NI == ".")
1453 ++NI;
1454 if (NI == NE)
1455 break;
1456
1457 // '.' components in Dir are ignored.
1458 while (DI != DE && *DI == ".")
1459 ++DI;
1460 if (DI == DE) {
1461 // Dir is a prefix of Name, up to '.' components and choice of path
1462 // separators.
1463 unsigned PrefixLength = NI - llvm::sys::path::begin(Name);
1464 if (PrefixLength > BestPrefixLength) {
1465 BestPrefixLength = PrefixLength;
1466 BestSearchDir = I;
1467 }
1468 break;
1469 }
1470
1471 if (*NI != *DI)
1472 break;
1473 }
1474 }
1475
1476 if (IsSystem)
1477 *IsSystem = BestPrefixLength ? BestSearchDir >= SystemDirIdx : false;
1478 return Name + BestPrefixLength;
1479 }
1480