diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Lex/HeaderSearch.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Lex/HeaderSearch.cpp | 99 |
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(); } |