aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Lex/HeaderSearch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Lex/HeaderSearch.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Lex/HeaderSearch.cpp99
1 files changed, 76 insertions, 23 deletions
diff --git a/contrib/llvm-project/clang/lib/Lex/HeaderSearch.cpp b/contrib/llvm-project/clang/lib/Lex/HeaderSearch.cpp
index d5adbcf62cbc..a0b60118a1a8 100644
--- a/contrib/llvm-project/clang/lib/Lex/HeaderSearch.cpp
+++ b/contrib/llvm-project/clang/lib/Lex/HeaderSearch.cpp
@@ -91,7 +91,7 @@ void HeaderSearch::PrintStats() {
<< FileInfo.size() << " files tracked.\n";
unsigned NumOnceOnlyFiles = 0, MaxNumIncludes = 0, NumSingleIncludedFiles = 0;
for (unsigned i = 0, e = FileInfo.size(); i != e; ++i) {
- NumOnceOnlyFiles += FileInfo[i].isImport;
+ NumOnceOnlyFiles += (FileInfo[i].isPragmaOnce || FileInfo[i].isImport);
if (MaxNumIncludes < FileInfo[i].NumIncludes)
MaxNumIncludes = FileInfo[i].NumIncludes;
NumSingleIncludedFiles += FileInfo[i].NumIncludes == 1;
@@ -108,6 +108,20 @@ void HeaderSearch::PrintStats() {
<< NumSubFrameworkLookups << " subframework lookups.\n";
}
+std::vector<bool> HeaderSearch::computeUserEntryUsage() const {
+ std::vector<bool> UserEntryUsage(HSOpts->UserEntries.size());
+ for (unsigned I = 0, E = SearchDirsUsage.size(); I < E; ++I) {
+ // Check whether this DirectoryLookup has been successfully used.
+ if (SearchDirsUsage[I]) {
+ auto UserEntryIdxIt = SearchDirToHSEntry.find(I);
+ // Check whether this DirectoryLookup maps to a HeaderSearch::UserEntry.
+ if (UserEntryIdxIt != SearchDirToHSEntry.end())
+ UserEntryUsage[UserEntryIdxIt->second] = true;
+ }
+ }
+ return UserEntryUsage;
+}
+
/// CreateHeaderMap - This method returns a HeaderMap for the specified
/// FileEntry, uniquing them through the 'HeaderMaps' datastructure.
const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) {
@@ -229,7 +243,8 @@ std::string HeaderSearch::getCachedModuleFileNameImpl(StringRef ModuleName,
return Result.str().str();
}
-Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch,
+Module *HeaderSearch::lookupModule(StringRef ModuleName,
+ SourceLocation ImportLoc, bool AllowSearch,
bool AllowExtraModuleMapSearch) {
// Look in the module map to determine if there is a module by this name.
Module *Module = ModMap.findModule(ModuleName);
@@ -237,7 +252,8 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch,
return Module;
StringRef SearchName = ModuleName;
- Module = lookupModule(ModuleName, SearchName, AllowExtraModuleMapSearch);
+ Module = lookupModule(ModuleName, SearchName, ImportLoc,
+ AllowExtraModuleMapSearch);
// The facility for "private modules" -- adjacent, optional module maps named
// module.private.modulemap that are supposed to define private submodules --
@@ -248,19 +264,23 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch,
// could force building unwanted dependencies into the parent module and cause
// dependency cycles.
if (!Module && SearchName.consume_back("_Private"))
- Module = lookupModule(ModuleName, SearchName, AllowExtraModuleMapSearch);
+ Module = lookupModule(ModuleName, SearchName, ImportLoc,
+ AllowExtraModuleMapSearch);
if (!Module && SearchName.consume_back("Private"))
- Module = lookupModule(ModuleName, SearchName, AllowExtraModuleMapSearch);
+ Module = lookupModule(ModuleName, SearchName, ImportLoc,
+ AllowExtraModuleMapSearch);
return Module;
}
Module *HeaderSearch::lookupModule(StringRef ModuleName, StringRef SearchName,
+ SourceLocation ImportLoc,
bool AllowExtraModuleMapSearch) {
Module *Module = nullptr;
+ unsigned Idx;
// Look through the various header search paths to load any available module
// maps, searching for a module map that describes this module.
- for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
+ for (Idx = 0; Idx != SearchDirs.size(); ++Idx) {
if (SearchDirs[Idx].isFramework()) {
// Search for or infer a module map for a framework. Here we use
// SearchName rather than ModuleName, to permit finding private modules
@@ -323,6 +343,9 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, StringRef SearchName,
break;
}
+ if (Module)
+ noteLookupUsage(Idx, ImportLoc);
+
return Module;
}
@@ -435,16 +458,19 @@ Optional<FileEntryRef> DirectoryLookup::LookupFile(
if (llvm::sys::path::is_relative(Dest)) {
MappedName.append(Dest.begin(), Dest.end());
Filename = StringRef(MappedName.begin(), MappedName.size());
- Optional<FileEntryRef> Result = HM->LookupFile(Filename, HS.getFileMgr());
- if (Result) {
- FixupSearchPath();
- return *Result;
- }
- } else if (auto Res = HS.getFileMgr().getOptionalFileRef(Dest)) {
+ Dest = HM->lookupFilename(Filename, Path);
+ }
+
+ if (auto Res = HS.getFileMgr().getOptionalFileRef(Dest)) {
FixupSearchPath();
return *Res;
}
+ // Header maps need to be marked as used whenever the filename matches.
+ // The case where the target file **exists** is handled by callee of this
+ // function as part of the regular logic that applies to include search paths.
+ // The case where the target file **does not exist** is handled here:
+ HS.noteLookupUsage(*HS.searchDirIdx(*this), IncludeLoc);
return None;
}
@@ -649,6 +675,21 @@ Optional<FileEntryRef> DirectoryLookup::DoFrameworkLookup(
return None;
}
+void HeaderSearch::cacheLookupSuccess(LookupFileCacheInfo &CacheLookup,
+ unsigned HitIdx, SourceLocation Loc) {
+ CacheLookup.HitIdx = HitIdx;
+ noteLookupUsage(HitIdx, Loc);
+}
+
+void HeaderSearch::noteLookupUsage(unsigned HitIdx, SourceLocation Loc) {
+ SearchDirsUsage[HitIdx] = true;
+
+ auto UserEntryIdxIt = SearchDirToHSEntry.find(HitIdx);
+ if (UserEntryIdxIt != SearchDirToHSEntry.end())
+ Diags.Report(Loc, diag::remark_pp_search_path_usage)
+ << HSOpts->UserEntries[UserEntryIdxIt->second].Path;
+}
+
void HeaderSearch::setTarget(const TargetInfo &Target) {
ModMap.setTarget(Target);
}
@@ -964,13 +1005,13 @@ Optional<FileEntryRef> HeaderSearch::LookupFile(
// If this file is found in a header map and uses the framework style of
// includes, then this header is part of a framework we're building.
- if (CurDir->isIndexHeaderMap()) {
+ if (CurDir->isHeaderMap() && isAngled) {
size_t SlashPos = Filename.find('/');
- if (SlashPos != StringRef::npos) {
+ if (SlashPos != StringRef::npos)
+ HFI.Framework =
+ getUniqueFrameworkName(StringRef(Filename.begin(), SlashPos));
+ if (CurDir->isIndexHeaderMap())
HFI.IndexHeaderMapHeader = 1;
- HFI.Framework = getUniqueFrameworkName(StringRef(Filename.begin(),
- SlashPos));
- }
}
if (checkMSVCHeaderSearch(Diags, MSFE ? &MSFE->getFileEntry() : nullptr,
@@ -987,7 +1028,7 @@ Optional<FileEntryRef> HeaderSearch::LookupFile(
&File->getFileEntry(), isAngled, FoundByHeaderMap);
// Remember this location for the next lookup we do.
- CacheLookup.HitIdx = i;
+ cacheLookupSuccess(CacheLookup, i, IncludeLoc);
return File;
}
@@ -996,7 +1037,7 @@ Optional<FileEntryRef> HeaderSearch::LookupFile(
// resolve "foo.h" any other way, change the include to <Foo/foo.h>, where
// "Foo" is the name of the framework in which the including header was found.
if (!Includers.empty() && Includers.front().first && !isAngled &&
- Filename.find('/') == StringRef::npos) {
+ !Filename.contains('/')) {
HeaderFileInfo &IncludingHFI = getFileInfo(Includers.front().first);
if (IncludingHFI.IndexHeaderMapHeader) {
SmallString<128> ScratchFilename;
@@ -1017,8 +1058,8 @@ Optional<FileEntryRef> HeaderSearch::LookupFile(
return MSFE;
}
- LookupFileCacheInfo &CacheLookup = LookupFileCache[Filename];
- CacheLookup.HitIdx = LookupFileCache[ScratchFilename].HitIdx;
+ cacheLookupSuccess(LookupFileCache[Filename],
+ LookupFileCache[ScratchFilename].HitIdx, IncludeLoc);
// FIXME: SuggestedModule.
return File;
}
@@ -1269,9 +1310,12 @@ void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE,
bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
const FileEntry *File, bool isImport,
- bool ModulesEnabled, Module *M) {
+ bool ModulesEnabled, Module *M,
+ bool &IsFirstIncludeOfFile) {
++NumIncluded; // Count # of attempted #includes.
+ IsFirstIncludeOfFile = false;
+
// Get information about this file.
HeaderFileInfo &FileInfo = getFileInfo(File);
@@ -1325,7 +1369,7 @@ bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
} else {
// Otherwise, if this is a #include of a file that was previously #import'd
// or if this is the second #include of a #pragma once file, ignore it.
- if (FileInfo.isImport && !TryEnterImported())
+ if ((FileInfo.isPragmaOnce || FileInfo.isImport) && !TryEnterImported())
return false;
}
@@ -1346,6 +1390,8 @@ bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
// Increment the number of times this file has been included.
++FileInfo.NumIncludes;
+ IsFirstIncludeOfFile = FileInfo.NumIncludes == 1;
+
return true;
}
@@ -1357,6 +1403,13 @@ size_t HeaderSearch::getTotalMemory() const {
+ FrameworkMap.getAllocator().getTotalMemory();
}
+Optional<unsigned> HeaderSearch::searchDirIdx(const DirectoryLookup &DL) const {
+ for (unsigned I = 0; I < SearchDirs.size(); ++I)
+ if (&SearchDirs[I] == &DL)
+ return I;
+ return None;
+}
+
StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) {
return FrameworkNames.insert(Framework).first->first();
}