Coverage Report

Created: 2022-01-25 06:29

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