1 //===- HeaderSearch.cpp - Resolve Header File Locations -------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the DirectoryLookup and HeaderSearch interfaces.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "clang/Lex/HeaderSearch.h"
14 #include "clang/Basic/Diagnostic.h"
15 #include "clang/Basic/FileManager.h"
16 #include "clang/Basic/IdentifierTable.h"
17 #include "clang/Basic/Module.h"
18 #include "clang/Basic/SourceManager.h"
19 #include "clang/Lex/DirectoryLookup.h"
20 #include "clang/Lex/ExternalPreprocessorSource.h"
21 #include "clang/Lex/HeaderMap.h"
22 #include "clang/Lex/HeaderSearchOptions.h"
23 #include "clang/Lex/LexDiagnostic.h"
24 #include "clang/Lex/ModuleMap.h"
25 #include "clang/Lex/Preprocessor.h"
26 #include "llvm/ADT/APInt.h"
27 #include "llvm/ADT/Hashing.h"
28 #include "llvm/ADT/SmallString.h"
29 #include "llvm/ADT/SmallVector.h"
30 #include "llvm/ADT/Statistic.h"
31 #include "llvm/ADT/StringRef.h"
32 #include "llvm/ADT/STLExtras.h"
33 #include "llvm/Support/Allocator.h"
34 #include "llvm/Support/Capacity.h"
35 #include "llvm/Support/Errc.h"
36 #include "llvm/Support/ErrorHandling.h"
37 #include "llvm/Support/FileSystem.h"
38 #include "llvm/Support/Path.h"
39 #include "llvm/Support/VirtualFileSystem.h"
40 #include <algorithm>
41 #include <cassert>
42 #include <cstddef>
43 #include <cstdio>
44 #include <cstring>
45 #include <string>
46 #include <system_error>
47 #include <utility>
48
49 using namespace clang;
50
51 #define DEBUG_TYPE "file-search"
52
53 ALWAYS_ENABLED_STATISTIC(NumIncluded, "Number of attempted #includes.");
54 ALWAYS_ENABLED_STATISTIC(
55 NumMultiIncludeFileOptzn,
56 "Number of #includes skipped due to the multi-include optimization.");
57 ALWAYS_ENABLED_STATISTIC(NumFrameworkLookups, "Number of framework lookups.");
58 ALWAYS_ENABLED_STATISTIC(NumSubFrameworkLookups,
59 "Number of subframework lookups.");
60
61 const IdentifierInfo *
getControllingMacro(ExternalPreprocessorSource * External)62 HeaderFileInfo::getControllingMacro(ExternalPreprocessorSource *External) {
63 if (ControllingMacro) {
64 if (ControllingMacro->isOutOfDate()) {
65 assert(External && "We must have an external source if we have a "
66 "controlling macro that is out of date.");
67 External->updateOutOfDateIdentifier(
68 *const_cast<IdentifierInfo *>(ControllingMacro));
69 }
70 return ControllingMacro;
71 }
72
73 if (!ControllingMacroID || !External)
74 return nullptr;
75
76 ControllingMacro = External->GetIdentifier(ControllingMacroID);
77 return ControllingMacro;
78 }
79
80 ExternalHeaderFileInfoSource::~ExternalHeaderFileInfoSource() = default;
81
HeaderSearch(std::shared_ptr<HeaderSearchOptions> HSOpts,SourceManager & SourceMgr,DiagnosticsEngine & Diags,const LangOptions & LangOpts,const TargetInfo * Target)82 HeaderSearch::HeaderSearch(std::shared_ptr<HeaderSearchOptions> HSOpts,
83 SourceManager &SourceMgr, DiagnosticsEngine &Diags,
84 const LangOptions &LangOpts,
85 const TargetInfo *Target)
86 : HSOpts(std::move(HSOpts)), Diags(Diags),
87 FileMgr(SourceMgr.getFileManager()), FrameworkMap(64),
88 ModMap(SourceMgr, Diags, LangOpts, Target, *this) {}
89
PrintStats()90 void HeaderSearch::PrintStats() {
91 llvm::errs() << "\n*** HeaderSearch Stats:\n"
92 << FileInfo.size() << " files tracked.\n";
93 unsigned NumOnceOnlyFiles = 0;
94 for (unsigned i = 0, e = FileInfo.size(); i != e; ++i)
95 NumOnceOnlyFiles += (FileInfo[i].isPragmaOnce || FileInfo[i].isImport);
96 llvm::errs() << " " << NumOnceOnlyFiles << " #import/#pragma once files.\n";
97
98 llvm::errs() << " " << NumIncluded << " #include/#include_next/#import.\n"
99 << " " << NumMultiIncludeFileOptzn
100 << " #includes skipped due to the multi-include optimization.\n";
101
102 llvm::errs() << NumFrameworkLookups << " framework lookups.\n"
103 << NumSubFrameworkLookups << " subframework lookups.\n";
104 }
105
SetSearchPaths(std::vector<DirectoryLookup> dirs,unsigned int angledDirIdx,unsigned int systemDirIdx,bool noCurDirSearch,llvm::DenseMap<unsigned int,unsigned int> searchDirToHSEntry)106 void HeaderSearch::SetSearchPaths(
107 std::vector<DirectoryLookup> dirs, unsigned int angledDirIdx,
108 unsigned int systemDirIdx, bool noCurDirSearch,
109 llvm::DenseMap<unsigned int, unsigned int> searchDirToHSEntry) {
110 assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() &&
111 "Directory indices are unordered");
112 SearchDirs = std::move(dirs);
113 SearchDirsUsage.assign(SearchDirs.size(), false);
114 AngledDirIdx = angledDirIdx;
115 SystemDirIdx = systemDirIdx;
116 NoCurDirSearch = noCurDirSearch;
117 SearchDirToHSEntry = std::move(searchDirToHSEntry);
118 //LookupFileCache.clear();
119 }
120
AddSearchPath(const DirectoryLookup & dir,bool isAngled)121 void HeaderSearch::AddSearchPath(const DirectoryLookup &dir, bool isAngled) {
122 unsigned idx = isAngled ? SystemDirIdx : AngledDirIdx;
123 SearchDirs.insert(SearchDirs.begin() + idx, dir);
124 SearchDirsUsage.insert(SearchDirsUsage.begin() + idx, false);
125 if (!isAngled)
126 AngledDirIdx++;
127 SystemDirIdx++;
128 }
129
computeUserEntryUsage() const130 std::vector<bool> HeaderSearch::computeUserEntryUsage() const {
131 std::vector<bool> UserEntryUsage(HSOpts->UserEntries.size());
132 for (unsigned I = 0, E = SearchDirsUsage.size(); I < E; ++I) {
133 // Check whether this DirectoryLookup has been successfully used.
134 if (SearchDirsUsage[I]) {
135 auto UserEntryIdxIt = SearchDirToHSEntry.find(I);
136 // Check whether this DirectoryLookup maps to a HeaderSearch::UserEntry.
137 if (UserEntryIdxIt != SearchDirToHSEntry.end())
138 UserEntryUsage[UserEntryIdxIt->second] = true;
139 }
140 }
141 return UserEntryUsage;
142 }
143
144 /// CreateHeaderMap - This method returns a HeaderMap for the specified
145 /// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
CreateHeaderMap(const FileEntry * FE)146 const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) {
147 // We expect the number of headermaps to be small, and almost always empty.
148 // If it ever grows, use of a linear search should be re-evaluated.
149 if (!HeaderMaps.empty()) {
150 for (unsigned i = 0, e = HeaderMaps.size(); i != e; ++i)
151 // Pointer equality comparison of FileEntries works because they are
152 // already uniqued by inode.
153 if (HeaderMaps[i].first == FE)
154 return HeaderMaps[i].second.get();
155 }
156
157 if (std::unique_ptr<HeaderMap> HM = HeaderMap::Create(FE, FileMgr)) {
158 HeaderMaps.emplace_back(FE, std::move(HM));
159 return HeaderMaps.back().second.get();
160 }
161
162 return nullptr;
163 }
164
165 /// Get filenames for all registered header maps.
getHeaderMapFileNames(SmallVectorImpl<std::string> & Names) const166 void HeaderSearch::getHeaderMapFileNames(
167 SmallVectorImpl<std::string> &Names) const {
168 for (auto &HM : HeaderMaps)
169 Names.push_back(std::string(HM.first->getName()));
170 }
171
getCachedModuleFileName(Module * Module)172 std::string HeaderSearch::getCachedModuleFileName(Module *Module) {
173 const FileEntry *ModuleMap =
174 getModuleMap().getModuleMapFileForUniquing(Module);
175 // The ModuleMap maybe a nullptr, when we load a cached C++ module without
176 // *.modulemap file. In this case, just return an empty string.
177 if (ModuleMap == nullptr)
178 return {};
179 return getCachedModuleFileName(Module->Name, ModuleMap->getName());
180 }
181
getPrebuiltModuleFileName(StringRef ModuleName,bool FileMapOnly)182 std::string HeaderSearch::getPrebuiltModuleFileName(StringRef ModuleName,
183 bool FileMapOnly) {
184 // First check the module name to pcm file map.
185 auto i(HSOpts->PrebuiltModuleFiles.find(ModuleName));
186 if (i != HSOpts->PrebuiltModuleFiles.end())
187 return i->second;
188
189 if (FileMapOnly || HSOpts->PrebuiltModulePaths.empty())
190 return {};
191
192 // Then go through each prebuilt module directory and try to find the pcm
193 // file.
194 for (const std::string &Dir : HSOpts->PrebuiltModulePaths) {
195 SmallString<256> Result(Dir);
196 llvm::sys::fs::make_absolute(Result);
197 if (ModuleName.contains(':'))
198 // The separator of C++20 modules partitions (':') is not good for file
199 // systems, here clang and gcc choose '-' by default since it is not a
200 // valid character of C++ indentifiers. So we could avoid conflicts.
201 llvm::sys::path::append(Result, ModuleName.split(':').first + "-" +
202 ModuleName.split(':').second +
203 ".pcm");
204 else
205 llvm::sys::path::append(Result, ModuleName + ".pcm");
206 if (getFileMgr().getFile(Result.str()))
207 return std::string(Result);
208 }
209
210 return {};
211 }
212
getPrebuiltImplicitModuleFileName(Module * Module)213 std::string HeaderSearch::getPrebuiltImplicitModuleFileName(Module *Module) {
214 const FileEntry *ModuleMap =
215 getModuleMap().getModuleMapFileForUniquing(Module);
216 StringRef ModuleName = Module->Name;
217 StringRef ModuleMapPath = ModuleMap->getName();
218 StringRef ModuleCacheHash = HSOpts->DisableModuleHash ? "" : getModuleHash();
219 for (const std::string &Dir : HSOpts->PrebuiltModulePaths) {
220 SmallString<256> CachePath(Dir);
221 llvm::sys::fs::make_absolute(CachePath);
222 llvm::sys::path::append(CachePath, ModuleCacheHash);
223 std::string FileName =
224 getCachedModuleFileNameImpl(ModuleName, ModuleMapPath, CachePath);
225 if (!FileName.empty() && getFileMgr().getFile(FileName))
226 return FileName;
227 }
228 return {};
229 }
230
getCachedModuleFileName(StringRef ModuleName,StringRef ModuleMapPath)231 std::string HeaderSearch::getCachedModuleFileName(StringRef ModuleName,
232 StringRef ModuleMapPath) {
233 return getCachedModuleFileNameImpl(ModuleName, ModuleMapPath,
234 getModuleCachePath());
235 }
236
getCachedModuleFileNameImpl(StringRef ModuleName,StringRef ModuleMapPath,StringRef CachePath)237 std::string HeaderSearch::getCachedModuleFileNameImpl(StringRef ModuleName,
238 StringRef ModuleMapPath,
239 StringRef CachePath) {
240 // If we don't have a module cache path or aren't supposed to use one, we
241 // can't do anything.
242 if (CachePath.empty())
243 return {};
244
245 SmallString<256> Result(CachePath);
246 llvm::sys::fs::make_absolute(Result);
247
248 if (HSOpts->DisableModuleHash) {
249 llvm::sys::path::append(Result, ModuleName + ".pcm");
250 } else {
251 // Construct the name <ModuleName>-<hash of ModuleMapPath>.pcm which should
252 // ideally be globally unique to this particular module. Name collisions
253 // in the hash are safe (because any translation unit can only import one
254 // module with each name), but result in a loss of caching.
255 //
256 // To avoid false-negatives, we form as canonical a path as we can, and map
257 // to lower-case in case we're on a case-insensitive file system.
258 std::string Parent =
259 std::string(llvm::sys::path::parent_path(ModuleMapPath));
260 if (Parent.empty())
261 Parent = ".";
262 auto Dir = FileMgr.getDirectory(Parent);
263 if (!Dir)
264 return {};
265 auto DirName = FileMgr.getCanonicalName(*Dir);
266 auto FileName = llvm::sys::path::filename(ModuleMapPath);
267
268 llvm::hash_code Hash =
269 llvm::hash_combine(DirName.lower(), FileName.lower());
270
271 SmallString<128> HashStr;
272 llvm::APInt(64, size_t(Hash)).toStringUnsigned(HashStr, /*Radix*/36);
273 llvm::sys::path::append(Result, ModuleName + "-" + HashStr + ".pcm");
274 }
275 return Result.str().str();
276 }
277
lookupModule(StringRef ModuleName,SourceLocation ImportLoc,bool AllowSearch,bool AllowExtraModuleMapSearch)278 Module *HeaderSearch::lookupModule(StringRef ModuleName,
279 SourceLocation ImportLoc, bool AllowSearch,
280 bool AllowExtraModuleMapSearch) {
281 // Look in the module map to determine if there is a module by this name.
282 Module *Module = ModMap.findModule(ModuleName);
283 if (Module || !AllowSearch || !HSOpts->ImplicitModuleMaps)
284 return Module;
285
286 StringRef SearchName = ModuleName;
287 Module = lookupModule(ModuleName, SearchName, ImportLoc,
288 AllowExtraModuleMapSearch);
289
290 // The facility for "private modules" -- adjacent, optional module maps named
291 // module.private.modulemap that are supposed to define private submodules --
292 // may have different flavors of names: FooPrivate, Foo_Private and Foo.Private.
293 //
294 // Foo.Private is now deprecated in favor of Foo_Private. Users of FooPrivate
295 // should also rename to Foo_Private. Representing private as submodules
296 // could force building unwanted dependencies into the parent module and cause
297 // dependency cycles.
298 if (!Module && SearchName.consume_back("_Private"))
299 Module = lookupModule(ModuleName, SearchName, ImportLoc,
300 AllowExtraModuleMapSearch);
301 if (!Module && SearchName.consume_back("Private"))
302 Module = lookupModule(ModuleName, SearchName, ImportLoc,
303 AllowExtraModuleMapSearch);
304 return Module;
305 }
306
lookupModule(StringRef ModuleName,StringRef SearchName,SourceLocation ImportLoc,bool AllowExtraModuleMapSearch)307 Module *HeaderSearch::lookupModule(StringRef ModuleName, StringRef SearchName,
308 SourceLocation ImportLoc,
309 bool AllowExtraModuleMapSearch) {
310 Module *Module = nullptr;
311
312 // Look through the various header search paths to load any available module
313 // maps, searching for a module map that describes this module.
314 for (DirectoryLookup Dir : search_dir_range()) {
315 if (Dir.isFramework()) {
316 // Search for or infer a module map for a framework. Here we use
317 // SearchName rather than ModuleName, to permit finding private modules
318 // named FooPrivate in buggy frameworks named Foo.
319 SmallString<128> FrameworkDirName;
320 FrameworkDirName += Dir.getFrameworkDir()->getName();
321 llvm::sys::path::append(FrameworkDirName, SearchName + ".framework");
322 if (auto FrameworkDir =
323 FileMgr.getOptionalDirectoryRef(FrameworkDirName)) {
324 bool IsSystem = Dir.getDirCharacteristic() != SrcMgr::C_User;
325 Module = loadFrameworkModule(ModuleName, *FrameworkDir, IsSystem);
326 if (Module)
327 break;
328 }
329 }
330
331 // FIXME: Figure out how header maps and module maps will work together.
332
333 // Only deal with normal search directories.
334 if (!Dir.isNormalDir())
335 continue;
336
337 bool IsSystem = Dir.isSystemHeaderDirectory();
338 // Only returns None if not a normal directory, which we just checked
339 DirectoryEntryRef NormalDir = *Dir.getDirRef();
340 // Search for a module map file in this directory.
341 if (loadModuleMapFile(NormalDir, IsSystem,
342 /*IsFramework*/false) == LMM_NewlyLoaded) {
343 // We just loaded a module map file; check whether the module is
344 // available now.
345 Module = ModMap.findModule(ModuleName);
346 if (Module)
347 break;
348 }
349
350 // Search for a module map in a subdirectory with the same name as the
351 // module.
352 SmallString<128> NestedModuleMapDirName;
353 NestedModuleMapDirName = Dir.getDir()->getName();
354 llvm::sys::path::append(NestedModuleMapDirName, ModuleName);
355 if (loadModuleMapFile(NestedModuleMapDirName, IsSystem,
356 /*IsFramework*/false) == LMM_NewlyLoaded){
357 // If we just loaded a module map file, look for the module again.
358 Module = ModMap.findModule(ModuleName);
359 if (Module)
360 break;
361 }
362
363 // If we've already performed the exhaustive search for module maps in this
364 // search directory, don't do it again.
365 if (Dir.haveSearchedAllModuleMaps())
366 continue;
367
368 // Load all module maps in the immediate subdirectories of this search
369 // directory if ModuleName was from @import.
370 if (AllowExtraModuleMapSearch)
371 loadSubdirectoryModuleMaps(Dir);
372
373 // Look again for the module.
374 Module = ModMap.findModule(ModuleName);
375 if (Module)
376 break;
377 }
378
379 return Module;
380 }
381
382 //===----------------------------------------------------------------------===//
383 // File lookup within a DirectoryLookup scope
384 //===----------------------------------------------------------------------===//
385
386 /// getName - Return the directory or filename corresponding to this lookup
387 /// object.
getName() const388 StringRef DirectoryLookup::getName() const {
389 // FIXME: Use the name from \c DirectoryEntryRef.
390 if (isNormalDir())
391 return getDir()->getName();
392 if (isFramework())
393 return getFrameworkDir()->getName();
394 assert(isHeaderMap() && "Unknown DirectoryLookup");
395 return getHeaderMap()->getFileName();
396 }
397
getFileAndSuggestModule(StringRef FileName,SourceLocation IncludeLoc,const DirectoryEntry * Dir,bool IsSystemHeaderDir,Module * RequestingModule,ModuleMap::KnownHeader * SuggestedModule)398 Optional<FileEntryRef> HeaderSearch::getFileAndSuggestModule(
399 StringRef FileName, SourceLocation IncludeLoc, const DirectoryEntry *Dir,
400 bool IsSystemHeaderDir, Module *RequestingModule,
401 ModuleMap::KnownHeader *SuggestedModule) {
402 // If we have a module map that might map this header, load it and
403 // check whether we'll have a suggestion for a module.
404 auto File = getFileMgr().getFileRef(FileName, /*OpenFile=*/true);
405 if (!File) {
406 // For rare, surprising errors (e.g. "out of file handles"), diag the EC
407 // message.
408 std::error_code EC = llvm::errorToErrorCode(File.takeError());
409 if (EC != llvm::errc::no_such_file_or_directory &&
410 EC != llvm::errc::invalid_argument &&
411 EC != llvm::errc::is_a_directory && EC != llvm::errc::not_a_directory) {
412 Diags.Report(IncludeLoc, diag::err_cannot_open_file)
413 << FileName << EC.message();
414 }
415 return None;
416 }
417
418 // If there is a module that corresponds to this header, suggest it.
419 if (!findUsableModuleForHeader(
420 &File->getFileEntry(), Dir ? Dir : File->getFileEntry().getDir(),
421 RequestingModule, SuggestedModule, IsSystemHeaderDir))
422 return None;
423
424 return *File;
425 }
426
427 /// LookupFile - Lookup the specified file in this search path, returning it
428 /// 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 & IsFrameworkFound,bool & IsInHeaderMap,SmallVectorImpl<char> & MappedName) const429 Optional<FileEntryRef> DirectoryLookup::LookupFile(
430 StringRef &Filename, HeaderSearch &HS, SourceLocation IncludeLoc,
431 SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
432 Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
433 bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound,
434 bool &IsInHeaderMap, SmallVectorImpl<char> &MappedName) const {
435 InUserSpecifiedSystemFramework = false;
436 IsInHeaderMap = false;
437 MappedName.clear();
438
439 SmallString<1024> TmpDir;
440 if (isNormalDir()) {
441 // Concatenate the requested file onto the directory.
442 TmpDir = getDirRef()->getName();
443 llvm::sys::path::append(TmpDir, Filename);
444 if (SearchPath) {
445 StringRef SearchPathRef(getDirRef()->getName());
446 SearchPath->clear();
447 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
448 }
449 if (RelativePath) {
450 RelativePath->clear();
451 RelativePath->append(Filename.begin(), Filename.end());
452 }
453
454 return HS.getFileAndSuggestModule(TmpDir, IncludeLoc, getDir(),
455 isSystemHeaderDirectory(),
456 RequestingModule, SuggestedModule);
457 }
458
459 if (isFramework())
460 return DoFrameworkLookup(Filename, HS, SearchPath, RelativePath,
461 RequestingModule, SuggestedModule,
462 InUserSpecifiedSystemFramework, IsFrameworkFound);
463
464 assert(isHeaderMap() && "Unknown directory lookup");
465 const HeaderMap *HM = getHeaderMap();
466 SmallString<1024> Path;
467 StringRef Dest = HM->lookupFilename(Filename, Path);
468 if (Dest.empty())
469 return None;
470
471 IsInHeaderMap = true;
472
473 auto FixupSearchPath = [&]() {
474 if (SearchPath) {
475 StringRef SearchPathRef(getName());
476 SearchPath->clear();
477 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
478 }
479 if (RelativePath) {
480 RelativePath->clear();
481 RelativePath->append(Filename.begin(), Filename.end());
482 }
483 };
484
485 // Check if the headermap maps the filename to a framework include
486 // ("Foo.h" -> "Foo/Foo.h"), in which case continue header lookup using the
487 // framework include.
488 if (llvm::sys::path::is_relative(Dest)) {
489 MappedName.append(Dest.begin(), Dest.end());
490 Filename = StringRef(MappedName.begin(), MappedName.size());
491 Dest = HM->lookupFilename(Filename, Path);
492 }
493
494 if (auto Res = HS.getFileMgr().getOptionalFileRef(Dest)) {
495 FixupSearchPath();
496 return *Res;
497 }
498
499 // Header maps need to be marked as used whenever the filename matches.
500 // The case where the target file **exists** is handled by callee of this
501 // function as part of the regular logic that applies to include search paths.
502 // The case where the target file **does not exist** is handled here:
503 HS.noteLookupUsage(HS.searchDirIdx(*this), IncludeLoc);
504 return None;
505 }
506
507 /// Given a framework directory, find the top-most framework directory.
508 ///
509 /// \param FileMgr The file manager to use for directory lookups.
510 /// \param DirName The name of the framework directory.
511 /// \param SubmodulePath Will be populated with the submodule path from the
512 /// returned top-level module to the originally named framework.
513 static Optional<DirectoryEntryRef>
getTopFrameworkDir(FileManager & FileMgr,StringRef DirName,SmallVectorImpl<std::string> & SubmodulePath)514 getTopFrameworkDir(FileManager &FileMgr, StringRef DirName,
515 SmallVectorImpl<std::string> &SubmodulePath) {
516 assert(llvm::sys::path::extension(DirName) == ".framework" &&
517 "Not a framework directory");
518
519 // Note: as an egregious but useful hack we use the real path here, because
520 // frameworks moving between top-level frameworks to embedded frameworks tend
521 // to be symlinked, and we base the logical structure of modules on the
522 // physical layout. In particular, we need to deal with crazy includes like
523 //
524 // #include <Foo/Frameworks/Bar.framework/Headers/Wibble.h>
525 //
526 // where 'Bar' used to be embedded in 'Foo', is now a top-level framework
527 // which one should access with, e.g.,
528 //
529 // #include <Bar/Wibble.h>
530 //
531 // Similar issues occur when a top-level framework has moved into an
532 // embedded framework.
533 auto TopFrameworkDir = FileMgr.getOptionalDirectoryRef(DirName);
534
535 if (TopFrameworkDir)
536 DirName = FileMgr.getCanonicalName(*TopFrameworkDir);
537 do {
538 // Get the parent directory name.
539 DirName = llvm::sys::path::parent_path(DirName);
540 if (DirName.empty())
541 break;
542
543 // Determine whether this directory exists.
544 auto Dir = FileMgr.getOptionalDirectoryRef(DirName);
545 if (!Dir)
546 break;
547
548 // If this is a framework directory, then we're a subframework of this
549 // framework.
550 if (llvm::sys::path::extension(DirName) == ".framework") {
551 SubmodulePath.push_back(std::string(llvm::sys::path::stem(DirName)));
552 TopFrameworkDir = *Dir;
553 }
554 } while (true);
555
556 return TopFrameworkDir;
557 }
558
needModuleLookup(Module * RequestingModule,bool HasSuggestedModule)559 static bool needModuleLookup(Module *RequestingModule,
560 bool HasSuggestedModule) {
561 return HasSuggestedModule ||
562 (RequestingModule && RequestingModule->NoUndeclaredIncludes);
563 }
564
565 /// DoFrameworkLookup - Do a lookup of the specified file in the current
566 /// DirectoryLookup, which is a framework directory.
DoFrameworkLookup(StringRef Filename,HeaderSearch & HS,SmallVectorImpl<char> * SearchPath,SmallVectorImpl<char> * RelativePath,Module * RequestingModule,ModuleMap::KnownHeader * SuggestedModule,bool & InUserSpecifiedSystemFramework,bool & IsFrameworkFound) const567 Optional<FileEntryRef> DirectoryLookup::DoFrameworkLookup(
568 StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath,
569 SmallVectorImpl<char> *RelativePath, Module *RequestingModule,
570 ModuleMap::KnownHeader *SuggestedModule,
571 bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound) const {
572 FileManager &FileMgr = HS.getFileMgr();
573
574 // Framework names must have a '/' in the filename.
575 size_t SlashPos = Filename.find('/');
576 if (SlashPos == StringRef::npos)
577 return None;
578
579 // Find out if this is the home for the specified framework, by checking
580 // HeaderSearch. Possible answers are yes/no and unknown.
581 FrameworkCacheEntry &CacheEntry =
582 HS.LookupFrameworkCache(Filename.substr(0, SlashPos));
583
584 // If it is known and in some other directory, fail.
585 if (CacheEntry.Directory && CacheEntry.Directory != getFrameworkDirRef())
586 return None;
587
588 // Otherwise, construct the path to this framework dir.
589
590 // FrameworkName = "/System/Library/Frameworks/"
591 SmallString<1024> FrameworkName;
592 FrameworkName += getFrameworkDirRef()->getName();
593 if (FrameworkName.empty() || FrameworkName.back() != '/')
594 FrameworkName.push_back('/');
595
596 // FrameworkName = "/System/Library/Frameworks/Cocoa"
597 StringRef ModuleName(Filename.begin(), SlashPos);
598 FrameworkName += ModuleName;
599
600 // FrameworkName = "/System/Library/Frameworks/Cocoa.framework/"
601 FrameworkName += ".framework/";
602
603 // If the cache entry was unresolved, populate it now.
604 if (!CacheEntry.Directory) {
605 ++NumFrameworkLookups;
606
607 // If the framework dir doesn't exist, we fail.
608 auto Dir = FileMgr.getDirectory(FrameworkName);
609 if (!Dir)
610 return None;
611
612 // Otherwise, if it does, remember that this is the right direntry for this
613 // framework.
614 CacheEntry.Directory = getFrameworkDirRef();
615
616 // If this is a user search directory, check if the framework has been
617 // user-specified as a system framework.
618 if (getDirCharacteristic() == SrcMgr::C_User) {
619 SmallString<1024> SystemFrameworkMarker(FrameworkName);
620 SystemFrameworkMarker += ".system_framework";
621 if (llvm::sys::fs::exists(SystemFrameworkMarker)) {
622 CacheEntry.IsUserSpecifiedSystemFramework = true;
623 }
624 }
625 }
626
627 // Set out flags.
628 InUserSpecifiedSystemFramework = CacheEntry.IsUserSpecifiedSystemFramework;
629 IsFrameworkFound = CacheEntry.Directory.has_value();
630
631 if (RelativePath) {
632 RelativePath->clear();
633 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
634 }
635
636 // Check "/System/Library/Frameworks/Cocoa.framework/Headers/file.h"
637 unsigned OrigSize = FrameworkName.size();
638
639 FrameworkName += "Headers/";
640
641 if (SearchPath) {
642 SearchPath->clear();
643 // Without trailing '/'.
644 SearchPath->append(FrameworkName.begin(), FrameworkName.end()-1);
645 }
646
647 FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
648
649 auto File =
650 FileMgr.getOptionalFileRef(FrameworkName, /*OpenFile=*/!SuggestedModule);
651 if (!File) {
652 // Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h"
653 const char *Private = "Private";
654 FrameworkName.insert(FrameworkName.begin()+OrigSize, Private,
655 Private+strlen(Private));
656 if (SearchPath)
657 SearchPath->insert(SearchPath->begin()+OrigSize, Private,
658 Private+strlen(Private));
659
660 File = FileMgr.getOptionalFileRef(FrameworkName,
661 /*OpenFile=*/!SuggestedModule);
662 }
663
664 // If we found the header and are allowed to suggest a module, do so now.
665 if (File && needModuleLookup(RequestingModule, SuggestedModule)) {
666 // Find the framework in which this header occurs.
667 StringRef FrameworkPath = File->getFileEntry().getDir()->getName();
668 bool FoundFramework = false;
669 do {
670 // Determine whether this directory exists.
671 auto Dir = FileMgr.getDirectory(FrameworkPath);
672 if (!Dir)
673 break;
674
675 // If this is a framework directory, then we're a subframework of this
676 // framework.
677 if (llvm::sys::path::extension(FrameworkPath) == ".framework") {
678 FoundFramework = true;
679 break;
680 }
681
682 // Get the parent directory name.
683 FrameworkPath = llvm::sys::path::parent_path(FrameworkPath);
684 if (FrameworkPath.empty())
685 break;
686 } while (true);
687
688 bool IsSystem = getDirCharacteristic() != SrcMgr::C_User;
689 if (FoundFramework) {
690 if (!HS.findUsableModuleForFrameworkHeader(
691 &File->getFileEntry(), FrameworkPath, RequestingModule,
692 SuggestedModule, IsSystem))
693 return None;
694 } else {
695 if (!HS.findUsableModuleForHeader(&File->getFileEntry(), getDir(),
696 RequestingModule, SuggestedModule,
697 IsSystem))
698 return None;
699 }
700 }
701 if (File)
702 return *File;
703 return None;
704 }
705
cacheLookupSuccess(LookupFileCacheInfo & CacheLookup,ConstSearchDirIterator HitIt,SourceLocation Loc)706 void HeaderSearch::cacheLookupSuccess(LookupFileCacheInfo &CacheLookup,
707 ConstSearchDirIterator HitIt,
708 SourceLocation Loc) {
709 CacheLookup.HitIt = HitIt;
710 noteLookupUsage(HitIt.Idx, Loc);
711 }
712
noteLookupUsage(unsigned HitIdx,SourceLocation Loc)713 void HeaderSearch::noteLookupUsage(unsigned HitIdx, SourceLocation Loc) {
714 SearchDirsUsage[HitIdx] = true;
715
716 auto UserEntryIdxIt = SearchDirToHSEntry.find(HitIdx);
717 if (UserEntryIdxIt != SearchDirToHSEntry.end())
718 Diags.Report(Loc, diag::remark_pp_search_path_usage)
719 << HSOpts->UserEntries[UserEntryIdxIt->second].Path;
720 }
721
setTarget(const TargetInfo & Target)722 void HeaderSearch::setTarget(const TargetInfo &Target) {
723 ModMap.setTarget(Target);
724 }
725
726 //===----------------------------------------------------------------------===//
727 // Header File Location.
728 //===----------------------------------------------------------------------===//
729
730 /// Return true with a diagnostic if the file that MSVC would have found
731 /// fails to match the one that Clang would have found with MSVC header search
732 /// disabled.
checkMSVCHeaderSearch(DiagnosticsEngine & Diags,const FileEntry * MSFE,const FileEntry * FE,SourceLocation IncludeLoc)733 static bool checkMSVCHeaderSearch(DiagnosticsEngine &Diags,
734 const FileEntry *MSFE, const FileEntry *FE,
735 SourceLocation IncludeLoc) {
736 if (MSFE && FE != MSFE) {
737 Diags.Report(IncludeLoc, diag::ext_pp_include_search_ms) << MSFE->getName();
738 return true;
739 }
740 return false;
741 }
742
copyString(StringRef Str,llvm::BumpPtrAllocator & Alloc)743 static const char *copyString(StringRef Str, llvm::BumpPtrAllocator &Alloc) {
744 assert(!Str.empty());
745 char *CopyStr = Alloc.Allocate<char>(Str.size()+1);
746 std::copy(Str.begin(), Str.end(), CopyStr);
747 CopyStr[Str.size()] = '\0';
748 return CopyStr;
749 }
750
isFrameworkStylePath(StringRef Path,bool & IsPrivateHeader,SmallVectorImpl<char> & FrameworkName,SmallVectorImpl<char> & IncludeSpelling)751 static bool isFrameworkStylePath(StringRef Path, bool &IsPrivateHeader,
752 SmallVectorImpl<char> &FrameworkName,
753 SmallVectorImpl<char> &IncludeSpelling) {
754 using namespace llvm::sys;
755 path::const_iterator I = path::begin(Path);
756 path::const_iterator E = path::end(Path);
757 IsPrivateHeader = false;
758
759 // Detect different types of framework style paths:
760 //
761 // ...Foo.framework/{Headers,PrivateHeaders}
762 // ...Foo.framework/Versions/{A,Current}/{Headers,PrivateHeaders}
763 // ...Foo.framework/Frameworks/Nested.framework/{Headers,PrivateHeaders}
764 // ...<other variations with 'Versions' like in the above path>
765 //
766 // and some other variations among these lines.
767 int FoundComp = 0;
768 while (I != E) {
769 if (*I == "Headers") {
770 ++FoundComp;
771 } else if (*I == "PrivateHeaders") {
772 ++FoundComp;
773 IsPrivateHeader = true;
774 } else if (I->endswith(".framework")) {
775 StringRef Name = I->drop_back(10); // Drop .framework
776 // Need to reset the strings and counter to support nested frameworks.
777 FrameworkName.clear();
778 FrameworkName.append(Name.begin(), Name.end());
779 IncludeSpelling.clear();
780 IncludeSpelling.append(Name.begin(), Name.end());
781 FoundComp = 1;
782 } else if (FoundComp >= 2) {
783 IncludeSpelling.push_back('/');
784 IncludeSpelling.append(I->begin(), I->end());
785 }
786 ++I;
787 }
788
789 return !FrameworkName.empty() && FoundComp >= 2;
790 }
791
792 static void
diagnoseFrameworkInclude(DiagnosticsEngine & Diags,SourceLocation IncludeLoc,StringRef Includer,StringRef IncludeFilename,const FileEntry * IncludeFE,bool isAngled=false,bool FoundByHeaderMap=false)793 diagnoseFrameworkInclude(DiagnosticsEngine &Diags, SourceLocation IncludeLoc,
794 StringRef Includer, StringRef IncludeFilename,
795 const FileEntry *IncludeFE, bool isAngled = false,
796 bool FoundByHeaderMap = false) {
797 bool IsIncluderPrivateHeader = false;
798 SmallString<128> FromFramework, ToFramework;
799 SmallString<128> FromIncludeSpelling, ToIncludeSpelling;
800 if (!isFrameworkStylePath(Includer, IsIncluderPrivateHeader, FromFramework,
801 FromIncludeSpelling))
802 return;
803 bool IsIncludeePrivateHeader = false;
804 bool IsIncludeeInFramework =
805 isFrameworkStylePath(IncludeFE->getName(), IsIncludeePrivateHeader,
806 ToFramework, ToIncludeSpelling);
807
808 if (!isAngled && !FoundByHeaderMap) {
809 SmallString<128> NewInclude("<");
810 if (IsIncludeeInFramework) {
811 NewInclude += ToIncludeSpelling;
812 NewInclude += ">";
813 } else {
814 NewInclude += IncludeFilename;
815 NewInclude += ">";
816 }
817 Diags.Report(IncludeLoc, diag::warn_quoted_include_in_framework_header)
818 << IncludeFilename
819 << FixItHint::CreateReplacement(IncludeLoc, NewInclude);
820 }
821
822 // Headers in Foo.framework/Headers should not include headers
823 // from Foo.framework/PrivateHeaders, since this violates public/private
824 // API boundaries and can cause modular dependency cycles.
825 if (!IsIncluderPrivateHeader && IsIncludeeInFramework &&
826 IsIncludeePrivateHeader && FromFramework == ToFramework)
827 Diags.Report(IncludeLoc, diag::warn_framework_include_private_from_public)
828 << IncludeFilename;
829 }
830
831 /// LookupFile - Given a "foo" or \<foo> reference, look up the indicated file,
832 /// return null on failure. isAngled indicates whether the file reference is
833 /// for system \#include's or not (i.e. using <> instead of ""). Includers, if
834 /// non-empty, indicates where the \#including file(s) are, in case a relative
835 /// search is needed. Microsoft mode will pass all \#including files.
LookupFile(StringRef Filename,SourceLocation IncludeLoc,bool isAngled,ConstSearchDirIterator FromDir,ConstSearchDirIterator * CurDirArg,ArrayRef<std::pair<const FileEntry *,const DirectoryEntry * >> Includers,SmallVectorImpl<char> * SearchPath,SmallVectorImpl<char> * RelativePath,Module * RequestingModule,ModuleMap::KnownHeader * SuggestedModule,bool * IsMapped,bool * IsFrameworkFound,bool SkipCache,bool BuildSystemModule)836 Optional<FileEntryRef> HeaderSearch::LookupFile(
837 StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
838 ConstSearchDirIterator FromDir, ConstSearchDirIterator *CurDirArg,
839 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
840 SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
841 Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
842 bool *IsMapped, bool *IsFrameworkFound, bool SkipCache,
843 bool BuildSystemModule) {
844 ConstSearchDirIterator CurDirLocal = nullptr;
845 ConstSearchDirIterator &CurDir = CurDirArg ? *CurDirArg : CurDirLocal;
846
847 if (IsMapped)
848 *IsMapped = false;
849
850 if (IsFrameworkFound)
851 *IsFrameworkFound = false;
852
853 if (SuggestedModule)
854 *SuggestedModule = ModuleMap::KnownHeader();
855
856 // If 'Filename' is absolute, check to see if it exists and no searching.
857 if (llvm::sys::path::is_absolute(Filename)) {
858 CurDir = nullptr;
859
860 // If this was an #include_next "/absolute/file", fail.
861 if (FromDir)
862 return None;
863
864 if (SearchPath)
865 SearchPath->clear();
866 if (RelativePath) {
867 RelativePath->clear();
868 RelativePath->append(Filename.begin(), Filename.end());
869 }
870 // Otherwise, just return the file.
871 return getFileAndSuggestModule(Filename, IncludeLoc, nullptr,
872 /*IsSystemHeaderDir*/false,
873 RequestingModule, SuggestedModule);
874 }
875
876 // This is the header that MSVC's header search would have found.
877 ModuleMap::KnownHeader MSSuggestedModule;
878 Optional<FileEntryRef> MSFE;
879
880 // Unless disabled, check to see if the file is in the #includer's
881 // directory. This cannot be based on CurDir, because each includer could be
882 // a #include of a subdirectory (#include "foo/bar.h") and a subsequent
883 // include of "baz.h" should resolve to "whatever/foo/baz.h".
884 // This search is not done for <> headers.
885 if (!Includers.empty() && !isAngled && !NoCurDirSearch) {
886 SmallString<1024> TmpDir;
887 bool First = true;
888 for (const auto &IncluderAndDir : Includers) {
889 const FileEntry *Includer = IncluderAndDir.first;
890
891 // Concatenate the requested file onto the directory.
892 // FIXME: Portability. Filename concatenation should be in sys::Path.
893 TmpDir = IncluderAndDir.second->getName();
894 TmpDir.push_back('/');
895 TmpDir.append(Filename.begin(), Filename.end());
896
897 // FIXME: We don't cache the result of getFileInfo across the call to
898 // getFileAndSuggestModule, because it's a reference to an element of
899 // a container that could be reallocated across this call.
900 //
901 // If we have no includer, that means we're processing a #include
902 // from a module build. We should treat this as a system header if we're
903 // building a [system] module.
904 bool IncluderIsSystemHeader =
905 Includer ? getFileInfo(Includer).DirInfo != SrcMgr::C_User :
906 BuildSystemModule;
907 if (Optional<FileEntryRef> FE = getFileAndSuggestModule(
908 TmpDir, IncludeLoc, IncluderAndDir.second, IncluderIsSystemHeader,
909 RequestingModule, SuggestedModule)) {
910 if (!Includer) {
911 assert(First && "only first includer can have no file");
912 return FE;
913 }
914
915 // Leave CurDir unset.
916 // This file is a system header or C++ unfriendly if the old file is.
917 //
918 // Note that we only use one of FromHFI/ToHFI at once, due to potential
919 // reallocation of the underlying vector potentially making the first
920 // reference binding dangling.
921 HeaderFileInfo &FromHFI = getFileInfo(Includer);
922 unsigned DirInfo = FromHFI.DirInfo;
923 bool IndexHeaderMapHeader = FromHFI.IndexHeaderMapHeader;
924 StringRef Framework = FromHFI.Framework;
925
926 HeaderFileInfo &ToHFI = getFileInfo(&FE->getFileEntry());
927 ToHFI.DirInfo = DirInfo;
928 ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader;
929 ToHFI.Framework = Framework;
930
931 if (SearchPath) {
932 StringRef SearchPathRef(IncluderAndDir.second->getName());
933 SearchPath->clear();
934 SearchPath->append(SearchPathRef.begin(), SearchPathRef.end());
935 }
936 if (RelativePath) {
937 RelativePath->clear();
938 RelativePath->append(Filename.begin(), Filename.end());
939 }
940 if (First) {
941 diagnoseFrameworkInclude(Diags, IncludeLoc,
942 IncluderAndDir.second->getName(), Filename,
943 &FE->getFileEntry());
944 return FE;
945 }
946
947 // Otherwise, we found the path via MSVC header search rules. If
948 // -Wmsvc-include is enabled, we have to keep searching to see if we
949 // would've found this header in -I or -isystem directories.
950 if (Diags.isIgnored(diag::ext_pp_include_search_ms, IncludeLoc)) {
951 return FE;
952 } else {
953 MSFE = FE;
954 if (SuggestedModule) {
955 MSSuggestedModule = *SuggestedModule;
956 *SuggestedModule = ModuleMap::KnownHeader();
957 }
958 break;
959 }
960 }
961 First = false;
962 }
963 }
964
965 CurDir = nullptr;
966
967 // If this is a system #include, ignore the user #include locs.
968 ConstSearchDirIterator It =
969 isAngled ? angled_dir_begin() : search_dir_begin();
970
971 // If this is a #include_next request, start searching after the directory the
972 // file was found in.
973 if (FromDir)
974 It = FromDir;
975
976 // Cache all of the lookups performed by this method. Many headers are
977 // multiply included, and the "pragma once" optimization prevents them from
978 // being relex/pp'd, but they would still have to search through a
979 // (potentially huge) series of SearchDirs to find it.
980 LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename];
981
982 ConstSearchDirIterator NextIt = std::next(It);
983
984 // If the entry has been previously looked up, the first value will be
985 // non-zero. If the value is equal to i (the start point of our search), then
986 // this is a matching hit.
987 if (!SkipCache && CacheLookup.StartIt == NextIt) {
988 // Skip querying potentially lots of directories for this lookup.
989 if (CacheLookup.HitIt)
990 It = CacheLookup.HitIt;
991 if (CacheLookup.MappedName) {
992 Filename = CacheLookup.MappedName;
993 if (IsMapped)
994 *IsMapped = true;
995 }
996 } else {
997 // Otherwise, this is the first query, or the previous query didn't match
998 // our search start. We will fill in our found location below, so prime the
999 // start point value.
1000 CacheLookup.reset(/*NewStartIt=*/NextIt);
1001 }
1002
1003 SmallString<64> MappedName;
1004
1005 // Check each directory in sequence to see if it contains this file.
1006 for (; It != search_dir_end(); ++It) {
1007 bool InUserSpecifiedSystemFramework = false;
1008 bool IsInHeaderMap = false;
1009 bool IsFrameworkFoundInDir = false;
1010 Optional<FileEntryRef> File = It->LookupFile(
1011 Filename, *this, IncludeLoc, SearchPath, RelativePath, RequestingModule,
1012 SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir,
1013 IsInHeaderMap, MappedName);
1014 if (!MappedName.empty()) {
1015 assert(IsInHeaderMap && "MappedName should come from a header map");
1016 CacheLookup.MappedName =
1017 copyString(MappedName, LookupFileCache.getAllocator());
1018 }
1019 if (IsMapped)
1020 // A filename is mapped when a header map remapped it to a relative path
1021 // used in subsequent header search or to an absolute path pointing to an
1022 // existing file.
1023 *IsMapped |= (!MappedName.empty() || (IsInHeaderMap && File));
1024 if (IsFrameworkFound)
1025 // Because we keep a filename remapped for subsequent search directory
1026 // lookups, ignore IsFrameworkFoundInDir after the first remapping and not
1027 // just for remapping in a current search directory.
1028 *IsFrameworkFound |= (IsFrameworkFoundInDir && !CacheLookup.MappedName);
1029 if (!File)
1030 continue;
1031
1032 CurDir = It;
1033
1034 const auto FE = &File->getFileEntry();
1035 IncludeNames[FE] = Filename;
1036
1037 // This file is a system header or C++ unfriendly if the dir is.
1038 HeaderFileInfo &HFI = getFileInfo(FE);
1039 HFI.DirInfo = CurDir->getDirCharacteristic();
1040
1041 // If the directory characteristic is User but this framework was
1042 // user-specified to be treated as a system framework, promote the
1043 // characteristic.
1044 if (HFI.DirInfo == SrcMgr::C_User && InUserSpecifiedSystemFramework)
1045 HFI.DirInfo = SrcMgr::C_System;
1046
1047 // If the filename matches a known system header prefix, override
1048 // whether the file is a system header.
1049 for (unsigned j = SystemHeaderPrefixes.size(); j; --j) {
1050 if (Filename.startswith(SystemHeaderPrefixes[j-1].first)) {
1051 HFI.DirInfo = SystemHeaderPrefixes[j-1].second ? SrcMgr::C_System
1052 : SrcMgr::C_User;
1053 break;
1054 }
1055 }
1056
1057 // Set the `Framework` info if this file is in a header map with framework
1058 // style include spelling or found in a framework dir. The header map case
1059 // is possible when building frameworks which use header maps.
1060 if (CurDir->isHeaderMap() && isAngled) {
1061 size_t SlashPos = Filename.find('/');
1062 if (SlashPos != StringRef::npos)
1063 HFI.Framework =
1064 getUniqueFrameworkName(StringRef(Filename.begin(), SlashPos));
1065 if (CurDir->isIndexHeaderMap())
1066 HFI.IndexHeaderMapHeader = 1;
1067 } else if (CurDir->isFramework()) {
1068 size_t SlashPos = Filename.find('/');
1069 if (SlashPos != StringRef::npos)
1070 HFI.Framework =
1071 getUniqueFrameworkName(StringRef(Filename.begin(), SlashPos));
1072 }
1073
1074 if (checkMSVCHeaderSearch(Diags, MSFE ? &MSFE->getFileEntry() : nullptr,
1075 &File->getFileEntry(), IncludeLoc)) {
1076 if (SuggestedModule)
1077 *SuggestedModule = MSSuggestedModule;
1078 return MSFE;
1079 }
1080
1081 bool FoundByHeaderMap = !IsMapped ? false : *IsMapped;
1082 if (!Includers.empty())
1083 diagnoseFrameworkInclude(
1084 Diags, IncludeLoc, Includers.front().second->getName(), Filename,
1085 &File->getFileEntry(), isAngled, FoundByHeaderMap);
1086
1087 // Remember this location for the next lookup we do.
1088 cacheLookupSuccess(CacheLookup, It, IncludeLoc);
1089 return File;
1090 }
1091
1092 // If we are including a file with a quoted include "foo.h" from inside
1093 // a header in a framework that is currently being built, and we couldn't
1094 // resolve "foo.h" any other way, change the include to <Foo/foo.h>, where
1095 // "Foo" is the name of the framework in which the including header was found.
1096 if (!Includers.empty() && Includers.front().first && !isAngled &&
1097 !Filename.contains('/')) {
1098 HeaderFileInfo &IncludingHFI = getFileInfo(Includers.front().first);
1099 if (IncludingHFI.IndexHeaderMapHeader) {
1100 SmallString<128> ScratchFilename;
1101 ScratchFilename += IncludingHFI.Framework;
1102 ScratchFilename += '/';
1103 ScratchFilename += Filename;
1104
1105 Optional<FileEntryRef> File = LookupFile(
1106 ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir, &CurDir,
1107 Includers.front(), SearchPath, RelativePath, RequestingModule,
1108 SuggestedModule, IsMapped, /*IsFrameworkFound=*/nullptr);
1109
1110 if (checkMSVCHeaderSearch(Diags, MSFE ? &MSFE->getFileEntry() : nullptr,
1111 File ? &File->getFileEntry() : nullptr,
1112 IncludeLoc)) {
1113 if (SuggestedModule)
1114 *SuggestedModule = MSSuggestedModule;
1115 return MSFE;
1116 }
1117
1118 cacheLookupSuccess(LookupFileCache[Filename],
1119 LookupFileCache[ScratchFilename].HitIt, IncludeLoc);
1120 // FIXME: SuggestedModule.
1121 return File;
1122 }
1123 }
1124
1125 if (checkMSVCHeaderSearch(Diags, MSFE ? &MSFE->getFileEntry() : nullptr,
1126 nullptr, IncludeLoc)) {
1127 if (SuggestedModule)
1128 *SuggestedModule = MSSuggestedModule;
1129 return MSFE;
1130 }
1131
1132 // Otherwise, didn't find it. Remember we didn't find this.
1133 CacheLookup.HitIt = search_dir_end();
1134 return None;
1135 }
1136
1137 /// LookupSubframeworkHeader - Look up a subframework for the specified
1138 /// \#include file. For example, if \#include'ing <HIToolbox/HIToolbox.h> from
1139 /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox
1140 /// is a subframework within Carbon.framework. If so, return the FileEntry
1141 /// for the designated file, otherwise return null.
LookupSubframeworkHeader(StringRef Filename,const FileEntry * ContextFileEnt,SmallVectorImpl<char> * SearchPath,SmallVectorImpl<char> * RelativePath,Module * RequestingModule,ModuleMap::KnownHeader * SuggestedModule)1142 Optional<FileEntryRef> HeaderSearch::LookupSubframeworkHeader(
1143 StringRef Filename, const FileEntry *ContextFileEnt,
1144 SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
1145 Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule) {
1146 assert(ContextFileEnt && "No context file?");
1147
1148 // Framework names must have a '/' in the filename. Find it.
1149 // FIXME: Should we permit '\' on Windows?
1150 size_t SlashPos = Filename.find('/');
1151 if (SlashPos == StringRef::npos)
1152 return None;
1153
1154 // Look up the base framework name of the ContextFileEnt.
1155 StringRef ContextName = ContextFileEnt->getName();
1156
1157 // If the context info wasn't a framework, couldn't be a subframework.
1158 const unsigned DotFrameworkLen = 10;
1159 auto FrameworkPos = ContextName.find(".framework");
1160 if (FrameworkPos == StringRef::npos ||
1161 (ContextName[FrameworkPos + DotFrameworkLen] != '/' &&
1162 ContextName[FrameworkPos + DotFrameworkLen] != '\\'))
1163 return None;
1164
1165 SmallString<1024> FrameworkName(ContextName.data(), ContextName.data() +
1166 FrameworkPos +
1167 DotFrameworkLen + 1);
1168
1169 // Append Frameworks/HIToolbox.framework/
1170 FrameworkName += "Frameworks/";
1171 FrameworkName.append(Filename.begin(), Filename.begin()+SlashPos);
1172 FrameworkName += ".framework/";
1173
1174 auto &CacheLookup =
1175 *FrameworkMap.insert(std::make_pair(Filename.substr(0, SlashPos),
1176 FrameworkCacheEntry())).first;
1177
1178 // Some other location?
1179 if (CacheLookup.second.Directory &&
1180 CacheLookup.first().size() == FrameworkName.size() &&
1181 memcmp(CacheLookup.first().data(), &FrameworkName[0],
1182 CacheLookup.first().size()) != 0)
1183 return None;
1184
1185 // Cache subframework.
1186 if (!CacheLookup.second.Directory) {
1187 ++NumSubFrameworkLookups;
1188
1189 // If the framework dir doesn't exist, we fail.
1190 auto Dir = FileMgr.getOptionalDirectoryRef(FrameworkName);
1191 if (!Dir)
1192 return None;
1193
1194 // Otherwise, if it does, remember that this is the right direntry for this
1195 // framework.
1196 CacheLookup.second.Directory = Dir;
1197 }
1198
1199
1200 if (RelativePath) {
1201 RelativePath->clear();
1202 RelativePath->append(Filename.begin()+SlashPos+1, Filename.end());
1203 }
1204
1205 // Check ".../Frameworks/HIToolbox.framework/Headers/HIToolbox.h"
1206 SmallString<1024> HeadersFilename(FrameworkName);
1207 HeadersFilename += "Headers/";
1208 if (SearchPath) {
1209 SearchPath->clear();
1210 // Without trailing '/'.
1211 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1212 }
1213
1214 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1215 auto File = FileMgr.getOptionalFileRef(HeadersFilename, /*OpenFile=*/true);
1216 if (!File) {
1217 // Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h"
1218 HeadersFilename = FrameworkName;
1219 HeadersFilename += "PrivateHeaders/";
1220 if (SearchPath) {
1221 SearchPath->clear();
1222 // Without trailing '/'.
1223 SearchPath->append(HeadersFilename.begin(), HeadersFilename.end()-1);
1224 }
1225
1226 HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
1227 File = FileMgr.getOptionalFileRef(HeadersFilename, /*OpenFile=*/true);
1228
1229 if (!File)
1230 return None;
1231 }
1232
1233 // This file is a system header or C++ unfriendly if the old file is.
1234 //
1235 // Note that the temporary 'DirInfo' is required here, as either call to
1236 // getFileInfo could resize the vector and we don't want to rely on order
1237 // of evaluation.
1238 unsigned DirInfo = getFileInfo(ContextFileEnt).DirInfo;
1239 getFileInfo(&File->getFileEntry()).DirInfo = DirInfo;
1240
1241 FrameworkName.pop_back(); // remove the trailing '/'
1242 if (!findUsableModuleForFrameworkHeader(&File->getFileEntry(), FrameworkName,
1243 RequestingModule, SuggestedModule,
1244 /*IsSystem*/ false))
1245 return None;
1246
1247 return *File;
1248 }
1249
1250 //===----------------------------------------------------------------------===//
1251 // File Info Management.
1252 //===----------------------------------------------------------------------===//
1253
1254 /// Merge the header file info provided by \p OtherHFI into the current
1255 /// header file info (\p HFI)
mergeHeaderFileInfo(HeaderFileInfo & HFI,const HeaderFileInfo & OtherHFI)1256 static void mergeHeaderFileInfo(HeaderFileInfo &HFI,
1257 const HeaderFileInfo &OtherHFI) {
1258 assert(OtherHFI.External && "expected to merge external HFI");
1259
1260 HFI.isImport |= OtherHFI.isImport;
1261 HFI.isPragmaOnce |= OtherHFI.isPragmaOnce;
1262 HFI.isModuleHeader |= OtherHFI.isModuleHeader;
1263
1264 if (!HFI.ControllingMacro && !HFI.ControllingMacroID) {
1265 HFI.ControllingMacro = OtherHFI.ControllingMacro;
1266 HFI.ControllingMacroID = OtherHFI.ControllingMacroID;
1267 }
1268
1269 HFI.DirInfo = OtherHFI.DirInfo;
1270 HFI.External = (!HFI.IsValid || HFI.External);
1271 HFI.IsValid = true;
1272 HFI.IndexHeaderMapHeader = OtherHFI.IndexHeaderMapHeader;
1273
1274 if (HFI.Framework.empty())
1275 HFI.Framework = OtherHFI.Framework;
1276 }
1277
1278 /// getFileInfo - Return the HeaderFileInfo structure for the specified
1279 /// FileEntry.
getFileInfo(const FileEntry * FE)1280 HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) {
1281 if (FE->getUID() >= FileInfo.size())
1282 FileInfo.resize(FE->getUID() + 1);
1283
1284 HeaderFileInfo *HFI = &FileInfo[FE->getUID()];
1285 // FIXME: Use a generation count to check whether this is really up to date.
1286 if (ExternalSource && !HFI->Resolved) {
1287 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1288 if (ExternalHFI.IsValid) {
1289 HFI->Resolved = true;
1290 if (ExternalHFI.External)
1291 mergeHeaderFileInfo(*HFI, ExternalHFI);
1292 }
1293 }
1294
1295 HFI->IsValid = true;
1296 // We have local information about this header file, so it's no longer
1297 // strictly external.
1298 HFI->External = false;
1299 return *HFI;
1300 }
1301
1302 const HeaderFileInfo *
getExistingFileInfo(const FileEntry * FE,bool WantExternal) const1303 HeaderSearch::getExistingFileInfo(const FileEntry *FE,
1304 bool WantExternal) const {
1305 // If we have an external source, ensure we have the latest information.
1306 // FIXME: Use a generation count to check whether this is really up to date.
1307 HeaderFileInfo *HFI;
1308 if (ExternalSource) {
1309 if (FE->getUID() >= FileInfo.size()) {
1310 if (!WantExternal)
1311 return nullptr;
1312 FileInfo.resize(FE->getUID() + 1);
1313 }
1314
1315 HFI = &FileInfo[FE->getUID()];
1316 if (!WantExternal && (!HFI->IsValid || HFI->External))
1317 return nullptr;
1318 if (!HFI->Resolved) {
1319 auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
1320 if (ExternalHFI.IsValid) {
1321 HFI->Resolved = true;
1322 if (ExternalHFI.External)
1323 mergeHeaderFileInfo(*HFI, ExternalHFI);
1324 }
1325 }
1326 } else if (FE->getUID() >= FileInfo.size()) {
1327 return nullptr;
1328 } else {
1329 HFI = &FileInfo[FE->getUID()];
1330 }
1331
1332 if (!HFI->IsValid || (HFI->External && !WantExternal))
1333 return nullptr;
1334
1335 return HFI;
1336 }
1337
isFileMultipleIncludeGuarded(const FileEntry * File)1338 bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) {
1339 // Check if we've entered this file and found an include guard or #pragma
1340 // once. Note that we dor't check for #import, because that's not a property
1341 // of the file itself.
1342 if (auto *HFI = getExistingFileInfo(File))
1343 return HFI->isPragmaOnce || HFI->ControllingMacro ||
1344 HFI->ControllingMacroID;
1345 return false;
1346 }
1347
MarkFileModuleHeader(const FileEntry * FE,ModuleMap::ModuleHeaderRole Role,bool isCompilingModuleHeader)1348 void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE,
1349 ModuleMap::ModuleHeaderRole Role,
1350 bool isCompilingModuleHeader) {
1351 bool isModularHeader = !(Role & ModuleMap::TextualHeader);
1352
1353 // Don't mark the file info as non-external if there's nothing to change.
1354 if (!isCompilingModuleHeader) {
1355 if (!isModularHeader)
1356 return;
1357 auto *HFI = getExistingFileInfo(FE);
1358 if (HFI && HFI->isModuleHeader)
1359 return;
1360 }
1361
1362 auto &HFI = getFileInfo(FE);
1363 HFI.isModuleHeader |= isModularHeader;
1364 HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
1365 }
1366
ShouldEnterIncludeFile(Preprocessor & PP,const FileEntry * File,bool isImport,bool ModulesEnabled,Module * M,bool & IsFirstIncludeOfFile)1367 bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
1368 const FileEntry *File, bool isImport,
1369 bool ModulesEnabled, Module *M,
1370 bool &IsFirstIncludeOfFile) {
1371 ++NumIncluded; // Count # of attempted #includes.
1372
1373 IsFirstIncludeOfFile = false;
1374
1375 // Get information about this file.
1376 HeaderFileInfo &FileInfo = getFileInfo(File);
1377
1378 // FIXME: this is a workaround for the lack of proper modules-aware support
1379 // for #import / #pragma once
1380 auto TryEnterImported = [&]() -> bool {
1381 if (!ModulesEnabled)
1382 return false;
1383 // Ensure FileInfo bits are up to date.
1384 ModMap.resolveHeaderDirectives(File);
1385 // Modules with builtins are special; multiple modules use builtins as
1386 // modular headers, example:
1387 //
1388 // module stddef { header "stddef.h" export * }
1389 //
1390 // After module map parsing, this expands to:
1391 //
1392 // module stddef {
1393 // header "/path_to_builtin_dirs/stddef.h"
1394 // textual "stddef.h"
1395 // }
1396 //
1397 // It's common that libc++ and system modules will both define such
1398 // submodules. Make sure cached results for a builtin header won't
1399 // prevent other builtin modules from potentially entering the builtin
1400 // header. Note that builtins are header guarded and the decision to
1401 // actually enter them is postponed to the controlling macros logic below.
1402 bool TryEnterHdr = false;
1403 if (FileInfo.isCompilingModuleHeader && FileInfo.isModuleHeader)
1404 TryEnterHdr = ModMap.isBuiltinHeader(File);
1405
1406 // Textual headers can be #imported from different modules. Since ObjC
1407 // headers find in the wild might rely only on #import and do not contain
1408 // controlling macros, be conservative and only try to enter textual headers
1409 // if such macro is present.
1410 if (!FileInfo.isModuleHeader &&
1411 FileInfo.getControllingMacro(ExternalLookup))
1412 TryEnterHdr = true;
1413 return TryEnterHdr;
1414 };
1415
1416 // If this is a #import directive, check that we have not already imported
1417 // this header.
1418 if (isImport) {
1419 // If this has already been imported, don't import it again.
1420 FileInfo.isImport = true;
1421
1422 // Has this already been #import'ed or #include'd?
1423 if (PP.alreadyIncluded(File) && !TryEnterImported())
1424 return false;
1425 } else {
1426 // Otherwise, if this is a #include of a file that was previously #import'd
1427 // or if this is the second #include of a #pragma once file, ignore it.
1428 if ((FileInfo.isPragmaOnce || FileInfo.isImport) && !TryEnterImported())
1429 return false;
1430 }
1431
1432 // Next, check to see if the file is wrapped with #ifndef guards. If so, and
1433 // if the macro that guards it is defined, we know the #include has no effect.
1434 if (const IdentifierInfo *ControllingMacro
1435 = FileInfo.getControllingMacro(ExternalLookup)) {
1436 // If the header corresponds to a module, check whether the macro is already
1437 // defined in that module rather than checking in the current set of visible
1438 // modules.
1439 if (M ? PP.isMacroDefinedInLocalModule(ControllingMacro, M)
1440 : PP.isMacroDefined(ControllingMacro)) {
1441 ++NumMultiIncludeFileOptzn;
1442 return false;
1443 }
1444 }
1445
1446 IsFirstIncludeOfFile = PP.markIncluded(File);
1447
1448 return true;
1449 }
1450
getTotalMemory() const1451 size_t HeaderSearch::getTotalMemory() const {
1452 return SearchDirs.capacity()
1453 + llvm::capacity_in_bytes(FileInfo)
1454 + llvm::capacity_in_bytes(HeaderMaps)
1455 + LookupFileCache.getAllocator().getTotalMemory()
1456 + FrameworkMap.getAllocator().getTotalMemory();
1457 }
1458
searchDirIdx(const DirectoryLookup & DL) const1459 unsigned HeaderSearch::searchDirIdx(const DirectoryLookup &DL) const {
1460 return &DL - &*SearchDirs.begin();
1461 }
1462
getUniqueFrameworkName(StringRef Framework)1463 StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) {
1464 return FrameworkNames.insert(Framework).first->first();
1465 }
1466
getIncludeNameForHeader(const FileEntry * File) const1467 StringRef HeaderSearch::getIncludeNameForHeader(const FileEntry *File) const {
1468 auto It = IncludeNames.find(File);
1469 if (It == IncludeNames.end())
1470 return {};
1471 return It->second;
1472 }
1473
hasModuleMap(StringRef FileName,const DirectoryEntry * Root,bool IsSystem)1474 bool HeaderSearch::hasModuleMap(StringRef FileName,
1475 const DirectoryEntry *Root,
1476 bool IsSystem) {
1477 if (!HSOpts->ImplicitModuleMaps)
1478 return false;
1479
1480 SmallVector<const DirectoryEntry *, 2> FixUpDirectories;
1481
1482 StringRef DirName = FileName;
1483 do {
1484 // Get the parent directory name.
1485 DirName = llvm::sys::path::parent_path(DirName);
1486 if (DirName.empty())
1487 return false;
1488
1489 // Determine whether this directory exists.
1490 auto Dir = FileMgr.getOptionalDirectoryRef(DirName);
1491 if (!Dir)
1492 return false;
1493
1494 // Try to load the module map file in this directory.
1495 switch (loadModuleMapFile(*Dir, IsSystem,
1496 llvm::sys::path::extension(Dir->getName()) ==
1497 ".framework")) {
1498 case LMM_NewlyLoaded:
1499 case LMM_AlreadyLoaded:
1500 // Success. All of the directories we stepped through inherit this module
1501 // map file.
1502 for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I)
1503 DirectoryHasModuleMap[FixUpDirectories[I]] = true;
1504 return true;
1505
1506 case LMM_NoDirectory:
1507 case LMM_InvalidModuleMap:
1508 break;
1509 }
1510
1511 // If we hit the top of our search, we're done.
1512 if (*Dir == Root)
1513 return false;
1514
1515 // Keep track of all of the directories we checked, so we can mark them as
1516 // having module maps if we eventually do find a module map.
1517 FixUpDirectories.push_back(*Dir);
1518 } while (true);
1519 }
1520
1521 ModuleMap::KnownHeader
findModuleForHeader(const FileEntry * File,bool AllowTextual) const1522 HeaderSearch::findModuleForHeader(const FileEntry *File,
1523 bool AllowTextual) const {
1524 if (ExternalSource) {
1525 // Make sure the external source has handled header info about this file,
1526 // which includes whether the file is part of a module.
1527 (void)getExistingFileInfo(File);
1528 }
1529 return ModMap.findModuleForHeader(File, AllowTextual);
1530 }
1531
1532 ArrayRef<ModuleMap::KnownHeader>
findAllModulesForHeader(const FileEntry * File) const1533 HeaderSearch::findAllModulesForHeader(const FileEntry *File) const {
1534 if (ExternalSource) {
1535 // Make sure the external source has handled header info about this file,
1536 // which includes whether the file is part of a module.
1537 (void)getExistingFileInfo(File);
1538 }
1539 return ModMap.findAllModulesForHeader(File);
1540 }
1541
suggestModule(HeaderSearch & HS,const FileEntry * File,Module * RequestingModule,ModuleMap::KnownHeader * SuggestedModule)1542 static bool suggestModule(HeaderSearch &HS, const FileEntry *File,
1543 Module *RequestingModule,
1544 ModuleMap::KnownHeader *SuggestedModule) {
1545 ModuleMap::KnownHeader Module =
1546 HS.findModuleForHeader(File, /*AllowTextual*/true);
1547
1548 // If this module specifies [no_undeclared_includes], we cannot find any
1549 // file that's in a non-dependency module.
1550 if (RequestingModule && Module && RequestingModule->NoUndeclaredIncludes) {
1551 HS.getModuleMap().resolveUses(RequestingModule, /*Complain*/ false);
1552 if (!RequestingModule->directlyUses(Module.getModule())) {
1553 // Builtin headers are a special case. Multiple modules can use the same
1554 // builtin as a modular header (see also comment in
1555 // ShouldEnterIncludeFile()), so the builtin header may have been
1556 // "claimed" by an unrelated module. This shouldn't prevent us from
1557 // including the builtin header textually in this module.
1558 if (HS.getModuleMap().isBuiltinHeader(File)) {
1559 if (SuggestedModule)
1560 *SuggestedModule = ModuleMap::KnownHeader();
1561 return true;
1562 }
1563 return false;
1564 }
1565 }
1566
1567 if (SuggestedModule)
1568 *SuggestedModule = (Module.getRole() & ModuleMap::TextualHeader)
1569 ? ModuleMap::KnownHeader()
1570 : Module;
1571
1572 return true;
1573 }
1574
findUsableModuleForHeader(const FileEntry * File,const DirectoryEntry * Root,Module * RequestingModule,ModuleMap::KnownHeader * SuggestedModule,bool IsSystemHeaderDir)1575 bool HeaderSearch::findUsableModuleForHeader(
1576 const FileEntry *File, const DirectoryEntry *Root, Module *RequestingModule,
1577 ModuleMap::KnownHeader *SuggestedModule, bool IsSystemHeaderDir) {
1578 if (File && needModuleLookup(RequestingModule, SuggestedModule)) {
1579 // If there is a module that corresponds to this header, suggest it.
1580 hasModuleMap(File->getName(), Root, IsSystemHeaderDir);
1581 return suggestModule(*this, File, RequestingModule, SuggestedModule);
1582 }
1583 return true;
1584 }
1585
findUsableModuleForFrameworkHeader(const FileEntry * File,StringRef FrameworkName,Module * RequestingModule,ModuleMap::KnownHeader * SuggestedModule,bool IsSystemFramework)1586 bool HeaderSearch::findUsableModuleForFrameworkHeader(
1587 const FileEntry *File, StringRef FrameworkName, Module *RequestingModule,
1588 ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework) {
1589 // If we're supposed to suggest a module, look for one now.
1590 if (needModuleLookup(RequestingModule, SuggestedModule)) {
1591 // Find the top-level framework based on this framework.
1592 SmallVector<std::string, 4> SubmodulePath;
1593 Optional<DirectoryEntryRef> TopFrameworkDir =
1594 ::getTopFrameworkDir(FileMgr, FrameworkName, SubmodulePath);
1595 assert(TopFrameworkDir && "Could not find the top-most framework dir");
1596
1597 // Determine the name of the top-level framework.
1598 StringRef ModuleName = llvm::sys::path::stem(TopFrameworkDir->getName());
1599
1600 // Load this framework module. If that succeeds, find the suggested module
1601 // for this header, if any.
1602 loadFrameworkModule(ModuleName, *TopFrameworkDir, IsSystemFramework);
1603
1604 // FIXME: This can find a module not part of ModuleName, which is
1605 // important so that we're consistent about whether this header
1606 // corresponds to a module. Possibly we should lock down framework modules
1607 // so that this is not possible.
1608 return suggestModule(*this, File, RequestingModule, SuggestedModule);
1609 }
1610 return true;
1611 }
1612
getPrivateModuleMap(const FileEntry * File,FileManager & FileMgr)1613 static const FileEntry *getPrivateModuleMap(const FileEntry *File,
1614 FileManager &FileMgr) {
1615 StringRef Filename = llvm::sys::path::filename(File->getName());
1616 SmallString<128> PrivateFilename(File->getDir()->getName());
1617 if (Filename == "module.map")
1618 llvm::sys::path::append(PrivateFilename, "module_private.map");
1619 else if (Filename == "module.modulemap")
1620 llvm::sys::path::append(PrivateFilename, "module.private.modulemap");
1621 else
1622 return nullptr;
1623 if (auto File = FileMgr.getFile(PrivateFilename))
1624 return *File;
1625 return nullptr;
1626 }
1627
loadModuleMapFile(const FileEntry * File,bool IsSystem,FileID ID,unsigned * Offset,StringRef OriginalModuleMapFile)1628 bool HeaderSearch::loadModuleMapFile(const FileEntry *File, bool IsSystem,
1629 FileID ID, unsigned *Offset,
1630 StringRef OriginalModuleMapFile) {
1631 // Find the directory for the module. For frameworks, that may require going
1632 // up from the 'Modules' directory.
1633 Optional<DirectoryEntryRef> Dir;
1634 if (getHeaderSearchOpts().ModuleMapFileHomeIsCwd) {
1635 Dir = FileMgr.getOptionalDirectoryRef(".");
1636 } else {
1637 if (!OriginalModuleMapFile.empty()) {
1638 // We're building a preprocessed module map. Find or invent the directory
1639 // that it originally occupied.
1640 Dir = FileMgr.getOptionalDirectoryRef(
1641 llvm::sys::path::parent_path(OriginalModuleMapFile));
1642 if (!Dir) {
1643 auto FakeFile = FileMgr.getVirtualFileRef(OriginalModuleMapFile, 0, 0);
1644 Dir = FakeFile.getDir();
1645 }
1646 } else {
1647 // TODO: Replace with `Dir = File.getDir()` when `File` is switched to
1648 // `FileEntryRef`.
1649 Dir = FileMgr.getOptionalDirectoryRef(File->getDir()->getName());
1650 }
1651
1652 assert(Dir && "parent must exist");
1653 StringRef DirName(Dir->getName());
1654 if (llvm::sys::path::filename(DirName) == "Modules") {
1655 DirName = llvm::sys::path::parent_path(DirName);
1656 if (DirName.endswith(".framework"))
1657 if (auto MaybeDir = FileMgr.getOptionalDirectoryRef(DirName))
1658 Dir = *MaybeDir;
1659 // FIXME: This assert can fail if there's a race between the above check
1660 // and the removal of the directory.
1661 assert(Dir && "parent must exist");
1662 }
1663 }
1664
1665 assert(Dir && "module map home directory must exist");
1666 switch (loadModuleMapFileImpl(File, IsSystem, *Dir, ID, Offset)) {
1667 case LMM_AlreadyLoaded:
1668 case LMM_NewlyLoaded:
1669 return false;
1670 case LMM_NoDirectory:
1671 case LMM_InvalidModuleMap:
1672 return true;
1673 }
1674 llvm_unreachable("Unknown load module map result");
1675 }
1676
1677 HeaderSearch::LoadModuleMapResult
loadModuleMapFileImpl(const FileEntry * File,bool IsSystem,DirectoryEntryRef Dir,FileID ID,unsigned * Offset)1678 HeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem,
1679 DirectoryEntryRef Dir, FileID ID,
1680 unsigned *Offset) {
1681 assert(File && "expected FileEntry");
1682
1683 // Check whether we've already loaded this module map, and mark it as being
1684 // loaded in case we recursively try to load it from itself.
1685 auto AddResult = LoadedModuleMaps.insert(std::make_pair(File, true));
1686 if (!AddResult.second)
1687 return AddResult.first->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1688
1689 if (ModMap.parseModuleMapFile(File, IsSystem, Dir, ID, Offset)) {
1690 LoadedModuleMaps[File] = false;
1691 return LMM_InvalidModuleMap;
1692 }
1693
1694 // Try to load a corresponding private module map.
1695 if (const FileEntry *PMMFile = getPrivateModuleMap(File, FileMgr)) {
1696 if (ModMap.parseModuleMapFile(PMMFile, IsSystem, Dir)) {
1697 LoadedModuleMaps[File] = false;
1698 return LMM_InvalidModuleMap;
1699 }
1700 }
1701
1702 // This directory has a module map.
1703 return LMM_NewlyLoaded;
1704 }
1705
1706 const FileEntry *
lookupModuleMapFile(const DirectoryEntry * Dir,bool IsFramework)1707 HeaderSearch::lookupModuleMapFile(const DirectoryEntry *Dir, bool IsFramework) {
1708 if (!HSOpts->ImplicitModuleMaps)
1709 return nullptr;
1710 // For frameworks, the preferred spelling is Modules/module.modulemap, but
1711 // module.map at the framework root is also accepted.
1712 SmallString<128> ModuleMapFileName(Dir->getName());
1713 if (IsFramework)
1714 llvm::sys::path::append(ModuleMapFileName, "Modules");
1715 llvm::sys::path::append(ModuleMapFileName, "module.modulemap");
1716 if (auto F = FileMgr.getFile(ModuleMapFileName))
1717 return *F;
1718
1719 // Continue to allow module.map
1720 ModuleMapFileName = Dir->getName();
1721 llvm::sys::path::append(ModuleMapFileName, "module.map");
1722 if (auto F = FileMgr.getFile(ModuleMapFileName))
1723 return *F;
1724
1725 // For frameworks, allow to have a private module map with a preferred
1726 // spelling when a public module map is absent.
1727 if (IsFramework) {
1728 ModuleMapFileName = Dir->getName();
1729 llvm::sys::path::append(ModuleMapFileName, "Modules",
1730 "module.private.modulemap");
1731 if (auto F = FileMgr.getFile(ModuleMapFileName))
1732 return *F;
1733 }
1734 return nullptr;
1735 }
1736
loadFrameworkModule(StringRef Name,DirectoryEntryRef Dir,bool IsSystem)1737 Module *HeaderSearch::loadFrameworkModule(StringRef Name, DirectoryEntryRef Dir,
1738 bool IsSystem) {
1739 if (Module *Module = ModMap.findModule(Name))
1740 return Module;
1741
1742 // Try to load a module map file.
1743 switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/true)) {
1744 case LMM_InvalidModuleMap:
1745 // Try to infer a module map from the framework directory.
1746 if (HSOpts->ImplicitModuleMaps)
1747 ModMap.inferFrameworkModule(Dir, IsSystem, /*Parent=*/nullptr);
1748 break;
1749
1750 case LMM_AlreadyLoaded:
1751 case LMM_NoDirectory:
1752 return nullptr;
1753
1754 case LMM_NewlyLoaded:
1755 break;
1756 }
1757
1758 return ModMap.findModule(Name);
1759 }
1760
1761 HeaderSearch::LoadModuleMapResult
loadModuleMapFile(StringRef DirName,bool IsSystem,bool IsFramework)1762 HeaderSearch::loadModuleMapFile(StringRef DirName, bool IsSystem,
1763 bool IsFramework) {
1764 if (auto Dir = FileMgr.getOptionalDirectoryRef(DirName))
1765 return loadModuleMapFile(*Dir, IsSystem, IsFramework);
1766
1767 return LMM_NoDirectory;
1768 }
1769
1770 HeaderSearch::LoadModuleMapResult
loadModuleMapFile(DirectoryEntryRef Dir,bool IsSystem,bool IsFramework)1771 HeaderSearch::loadModuleMapFile(DirectoryEntryRef Dir, bool IsSystem,
1772 bool IsFramework) {
1773 auto KnownDir = DirectoryHasModuleMap.find(Dir);
1774 if (KnownDir != DirectoryHasModuleMap.end())
1775 return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap;
1776
1777 if (const FileEntry *ModuleMapFile = lookupModuleMapFile(Dir, IsFramework)) {
1778 LoadModuleMapResult Result =
1779 loadModuleMapFileImpl(ModuleMapFile, IsSystem, Dir);
1780 // Add Dir explicitly in case ModuleMapFile is in a subdirectory.
1781 // E.g. Foo.framework/Modules/module.modulemap
1782 // ^Dir ^ModuleMapFile
1783 if (Result == LMM_NewlyLoaded)
1784 DirectoryHasModuleMap[Dir] = true;
1785 else if (Result == LMM_InvalidModuleMap)
1786 DirectoryHasModuleMap[Dir] = false;
1787 return Result;
1788 }
1789 return LMM_InvalidModuleMap;
1790 }
1791
collectAllModules(SmallVectorImpl<Module * > & Modules)1792 void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) {
1793 Modules.clear();
1794
1795 if (HSOpts->ImplicitModuleMaps) {
1796 // Load module maps for each of the header search directories.
1797 for (DirectoryLookup &DL : search_dir_range()) {
1798 bool IsSystem = DL.isSystemHeaderDirectory();
1799 if (DL.isFramework()) {
1800 std::error_code EC;
1801 SmallString<128> DirNative;
1802 llvm::sys::path::native(DL.getFrameworkDir()->getName(), DirNative);
1803
1804 // Search each of the ".framework" directories to load them as modules.
1805 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1806 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
1807 DirEnd;
1808 Dir != DirEnd && !EC; Dir.increment(EC)) {
1809 if (llvm::sys::path::extension(Dir->path()) != ".framework")
1810 continue;
1811
1812 auto FrameworkDir = FileMgr.getOptionalDirectoryRef(Dir->path());
1813 if (!FrameworkDir)
1814 continue;
1815
1816 // Load this framework module.
1817 loadFrameworkModule(llvm::sys::path::stem(Dir->path()), *FrameworkDir,
1818 IsSystem);
1819 }
1820 continue;
1821 }
1822
1823 // FIXME: Deal with header maps.
1824 if (DL.isHeaderMap())
1825 continue;
1826
1827 // Try to load a module map file for the search directory.
1828 loadModuleMapFile(*DL.getDirRef(), IsSystem, /*IsFramework*/ false);
1829
1830 // Try to load module map files for immediate subdirectories of this
1831 // search directory.
1832 loadSubdirectoryModuleMaps(DL);
1833 }
1834 }
1835
1836 // Populate the list of modules.
1837 llvm::transform(ModMap.modules(), std::back_inserter(Modules),
1838 [](const auto &NameAndMod) { return NameAndMod.second; });
1839 }
1840
loadTopLevelSystemModules()1841 void HeaderSearch::loadTopLevelSystemModules() {
1842 if (!HSOpts->ImplicitModuleMaps)
1843 return;
1844
1845 // Load module maps for each of the header search directories.
1846 for (const DirectoryLookup &DL : search_dir_range()) {
1847 // We only care about normal header directories.
1848 if (!DL.isNormalDir())
1849 continue;
1850
1851 // Try to load a module map file for the search directory.
1852 loadModuleMapFile(*DL.getDirRef(), DL.isSystemHeaderDirectory(),
1853 DL.isFramework());
1854 }
1855 }
1856
loadSubdirectoryModuleMaps(DirectoryLookup & SearchDir)1857 void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) {
1858 assert(HSOpts->ImplicitModuleMaps &&
1859 "Should not be loading subdirectory module maps");
1860
1861 if (SearchDir.haveSearchedAllModuleMaps())
1862 return;
1863
1864 std::error_code EC;
1865 SmallString<128> Dir = SearchDir.getDir()->getName();
1866 FileMgr.makeAbsolutePath(Dir);
1867 SmallString<128> DirNative;
1868 llvm::sys::path::native(Dir, DirNative);
1869 llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
1870 for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
1871 Dir != DirEnd && !EC; Dir.increment(EC)) {
1872 bool IsFramework = llvm::sys::path::extension(Dir->path()) == ".framework";
1873 if (IsFramework == SearchDir.isFramework())
1874 loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(),
1875 SearchDir.isFramework());
1876 }
1877
1878 SearchDir.setSearchedAllModuleMaps(true);
1879 }
1880
suggestPathToFileForDiagnostics(const FileEntry * File,llvm::StringRef MainFile,bool * IsSystem)1881 std::string HeaderSearch::suggestPathToFileForDiagnostics(
1882 const FileEntry *File, llvm::StringRef MainFile, bool *IsSystem) {
1883 // FIXME: We assume that the path name currently cached in the FileEntry is
1884 // the most appropriate one for this analysis (and that it's spelled the
1885 // same way as the corresponding header search path).
1886 return suggestPathToFileForDiagnostics(File->getName(), /*WorkingDir=*/"",
1887 MainFile, IsSystem);
1888 }
1889
suggestPathToFileForDiagnostics(llvm::StringRef File,llvm::StringRef WorkingDir,llvm::StringRef MainFile,bool * IsSystem)1890 std::string HeaderSearch::suggestPathToFileForDiagnostics(
1891 llvm::StringRef File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,
1892 bool *IsSystem) {
1893 using namespace llvm::sys;
1894
1895 unsigned BestPrefixLength = 0;
1896 // Checks whether `Dir` is a strict path prefix of `File`. If so and that's
1897 // the longest prefix we've seen so for it, returns true and updates the
1898 // `BestPrefixLength` accordingly.
1899 auto CheckDir = [&](llvm::StringRef Dir) -> bool {
1900 llvm::SmallString<32> DirPath(Dir.begin(), Dir.end());
1901 if (!WorkingDir.empty() && !path::is_absolute(Dir))
1902 fs::make_absolute(WorkingDir, DirPath);
1903 path::remove_dots(DirPath, /*remove_dot_dot=*/true);
1904 Dir = DirPath;
1905 for (auto NI = path::begin(File), NE = path::end(File),
1906 DI = path::begin(Dir), DE = path::end(Dir);
1907 /*termination condition in loop*/; ++NI, ++DI) {
1908 // '.' components in File are ignored.
1909 while (NI != NE && *NI == ".")
1910 ++NI;
1911 if (NI == NE)
1912 break;
1913
1914 // '.' components in Dir are ignored.
1915 while (DI != DE && *DI == ".")
1916 ++DI;
1917 if (DI == DE) {
1918 // Dir is a prefix of File, up to '.' components and choice of path
1919 // separators.
1920 unsigned PrefixLength = NI - path::begin(File);
1921 if (PrefixLength > BestPrefixLength) {
1922 BestPrefixLength = PrefixLength;
1923 return true;
1924 }
1925 break;
1926 }
1927
1928 // Consider all path separators equal.
1929 if (NI->size() == 1 && DI->size() == 1 &&
1930 path::is_separator(NI->front()) && path::is_separator(DI->front()))
1931 continue;
1932
1933 // Special case Apple .sdk folders since the search path is typically a
1934 // symlink like `iPhoneSimulator14.5.sdk` while the file is instead
1935 // located in `iPhoneSimulator.sdk` (the real folder).
1936 if (NI->endswith(".sdk") && DI->endswith(".sdk")) {
1937 StringRef NBasename = path::stem(*NI);
1938 StringRef DBasename = path::stem(*DI);
1939 if (DBasename.startswith(NBasename))
1940 continue;
1941 }
1942
1943 if (*NI != *DI)
1944 break;
1945 }
1946 return false;
1947 };
1948
1949 bool BestPrefixIsFramework = false;
1950 for (const DirectoryLookup &DL : search_dir_range()) {
1951 if (DL.isNormalDir()) {
1952 StringRef Dir = DL.getDir()->getName();
1953 if (CheckDir(Dir)) {
1954 if (IsSystem)
1955 *IsSystem = BestPrefixLength && isSystem(DL.getDirCharacteristic());
1956 BestPrefixIsFramework = false;
1957 }
1958 } else if (DL.isFramework()) {
1959 StringRef Dir = DL.getFrameworkDir()->getName();
1960 if (CheckDir(Dir)) {
1961 if (IsSystem)
1962 *IsSystem = BestPrefixLength && isSystem(DL.getDirCharacteristic());
1963 BestPrefixIsFramework = true;
1964 }
1965 }
1966 }
1967
1968 // Try to shorten include path using TUs directory, if we couldn't find any
1969 // suitable prefix in include search paths.
1970 if (!BestPrefixLength && CheckDir(path::parent_path(MainFile))) {
1971 if (IsSystem)
1972 *IsSystem = false;
1973 BestPrefixIsFramework = false;
1974 }
1975
1976 // Try resolving resulting filename via reverse search in header maps,
1977 // key from header name is user preferred name for the include file.
1978 StringRef Filename = File.drop_front(BestPrefixLength);
1979 for (const DirectoryLookup &DL : search_dir_range()) {
1980 if (!DL.isHeaderMap())
1981 continue;
1982
1983 StringRef SpelledFilename =
1984 DL.getHeaderMap()->reverseLookupFilename(Filename);
1985 if (!SpelledFilename.empty()) {
1986 Filename = SpelledFilename;
1987 BestPrefixIsFramework = false;
1988 break;
1989 }
1990 }
1991
1992 // If the best prefix is a framework path, we need to compute the proper
1993 // include spelling for the framework header.
1994 bool IsPrivateHeader;
1995 SmallString<128> FrameworkName, IncludeSpelling;
1996 if (BestPrefixIsFramework &&
1997 isFrameworkStylePath(Filename, IsPrivateHeader, FrameworkName,
1998 IncludeSpelling)) {
1999 Filename = IncludeSpelling;
2000 }
2001 return path::convert_to_slash(Filename);
2002 }
2003