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