From 786b503f66b1a35f79312203fcb533ad27511982 Mon Sep 17 00:00:00 2001 From: Jun Zhang Date: Sat, 6 Aug 2022 11:36:02 +0800 Subject: [Clang][Lex] Extend HeaderSearch::LookupFile to control OpenFile behavior. In the case of static compilation the file system is pretty much read-only and taking a snapshot of it usually is sufficient. In the interactive C++ case the compilation is longer and people can create and include files, etc. In that case we often do not want to open files or cache failures unless is absolutely necessary. This patch extends the original API call by forwarding some optional flags, so we can continue use it in the previous way with no breakage. Signed-off-by: Jun Zhang Differential Revision: https://reviews.llvm.org/D131241 --- clang/include/clang/Lex/DirectoryLookup.h | 3 ++- clang/include/clang/Lex/HeaderSearch.h | 6 ++++-- clang/include/clang/Lex/Preprocessor.h | 3 ++- clang/lib/Lex/HeaderSearch.cpp | 25 ++++++++++++++----------- clang/lib/Lex/PPDirectives.cpp | 4 ++-- 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/clang/include/clang/Lex/DirectoryLookup.h b/clang/include/clang/Lex/DirectoryLookup.h index 3602662029a4..d43b105606f7 100644 --- a/clang/include/clang/Lex/DirectoryLookup.h +++ b/clang/include/clang/Lex/DirectoryLookup.h @@ -186,7 +186,8 @@ public: SmallVectorImpl *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound, - bool &IsInHeaderMap, SmallVectorImpl &MappedName) const; + bool &IsInHeaderMap, SmallVectorImpl &MappedName, + bool OpenFile = true) const; private: Optional DoFrameworkLookup( diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h index 1b7eda333b6b..e438385f2550 100644 --- a/clang/include/clang/Lex/HeaderSearch.h +++ b/clang/include/clang/Lex/HeaderSearch.h @@ -474,7 +474,8 @@ public: SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool *IsFrameworkFound, bool SkipCache = false, - bool BuildSystemModule = false); + bool BuildSystemModule = false, bool OpenFile = true, + bool CacheFailures = true); /// Look up a subframework for the specified \#include file. /// @@ -759,7 +760,8 @@ private: getFileAndSuggestModule(StringRef FileName, SourceLocation IncludeLoc, const DirectoryEntry *Dir, bool IsSystemHeaderDir, Module *RequestingModule, - ModuleMap::KnownHeader *SuggestedModule); + ModuleMap::KnownHeader *SuggestedModule, + bool OpenFile = true, bool CacheFailures = true); /// Cache the result of a successful lookup at the given include location /// using the search path at \c HitIt. diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 79454b5addea..6e2517632717 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -2228,7 +2228,8 @@ public: ConstSearchDirIterator *CurDir, SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, - bool *IsFrameworkFound, bool SkipCache = false); + bool *IsFrameworkFound, bool SkipCache = false, + bool OpenFile = true, bool CacheFailures = true); /// Return true if we're in the top-level file, not in a \#include. bool isInPrimaryFile() const; diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp index 60fd42bc1127..219c62663ebd 100644 --- a/clang/lib/Lex/HeaderSearch.cpp +++ b/clang/lib/Lex/HeaderSearch.cpp @@ -398,10 +398,11 @@ StringRef DirectoryLookup::getName() const { Optional HeaderSearch::getFileAndSuggestModule( StringRef FileName, SourceLocation IncludeLoc, const DirectoryEntry *Dir, bool IsSystemHeaderDir, Module *RequestingModule, - ModuleMap::KnownHeader *SuggestedModule) { + ModuleMap::KnownHeader *SuggestedModule, bool OpenFile /*=true*/, + bool CacheFailures /*=true*/) { // If we have a module map that might map this header, load it and // check whether we'll have a suggestion for a module. - auto File = getFileMgr().getFileRef(FileName, /*OpenFile=*/true); + auto File = getFileMgr().getFileRef(FileName, OpenFile, CacheFailures); if (!File) { // For rare, surprising errors (e.g. "out of file handles"), diag the EC // message. @@ -431,7 +432,8 @@ Optional DirectoryLookup::LookupFile( SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool &InUserSpecifiedSystemFramework, bool &IsFrameworkFound, - bool &IsInHeaderMap, SmallVectorImpl &MappedName) const { + bool &IsInHeaderMap, SmallVectorImpl &MappedName, + bool OpenFile) const { InUserSpecifiedSystemFramework = false; IsInHeaderMap = false; MappedName.clear(); @@ -451,9 +453,9 @@ Optional DirectoryLookup::LookupFile( RelativePath->append(Filename.begin(), Filename.end()); } - return HS.getFileAndSuggestModule(TmpDir, IncludeLoc, getDir(), - isSystemHeaderDirectory(), - RequestingModule, SuggestedModule); + return HS.getFileAndSuggestModule( + TmpDir, IncludeLoc, getDir(), isSystemHeaderDirectory(), + RequestingModule, SuggestedModule, OpenFile); } if (isFramework()) @@ -491,7 +493,7 @@ Optional DirectoryLookup::LookupFile( Dest = HM->lookupFilename(Filename, Path); } - if (auto Res = HS.getFileMgr().getOptionalFileRef(Dest)) { + if (auto Res = HS.getFileMgr().getOptionalFileRef(Dest, OpenFile)) { FixupSearchPath(); return *Res; } @@ -840,7 +842,7 @@ Optional HeaderSearch::LookupFile( SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool *IsFrameworkFound, bool SkipCache, - bool BuildSystemModule) { + bool BuildSystemModule, bool OpenFile, bool CacheFailures) { ConstSearchDirIterator CurDirLocal = nullptr; ConstSearchDirIterator &CurDir = CurDirArg ? *CurDirArg : CurDirLocal; @@ -869,8 +871,9 @@ Optional HeaderSearch::LookupFile( } // Otherwise, just return the file. return getFileAndSuggestModule(Filename, IncludeLoc, nullptr, - /*IsSystemHeaderDir*/false, - RequestingModule, SuggestedModule); + /*IsSystemHeaderDir*/ false, + RequestingModule, SuggestedModule, OpenFile, + CacheFailures); } // This is the header that MSVC's header search would have found. @@ -1010,7 +1013,7 @@ Optional HeaderSearch::LookupFile( Optional File = It->LookupFile( Filename, *this, IncludeLoc, SearchPath, RelativePath, RequestingModule, SuggestedModule, InUserSpecifiedSystemFramework, IsFrameworkFoundInDir, - IsInHeaderMap, MappedName); + IsInHeaderMap, MappedName, OpenFile); if (!MappedName.empty()) { assert(IsInHeaderMap && "MappedName should come from a header map"); CacheLookup.MappedName = diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index 9a8fd4391b41..08ac45710e04 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -949,7 +949,7 @@ Optional Preprocessor::LookupFile( ConstSearchDirIterator *CurDirArg, SmallVectorImpl *SearchPath, SmallVectorImpl *RelativePath, ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, - bool *IsFrameworkFound, bool SkipCache) { + bool *IsFrameworkFound, bool SkipCache, bool OpenFile, bool CacheFailures) { ConstSearchDirIterator CurDirLocal = nullptr; ConstSearchDirIterator &CurDir = CurDirArg ? *CurDirArg : CurDirLocal; @@ -1028,7 +1028,7 @@ Optional Preprocessor::LookupFile( Optional FE = HeaderInfo.LookupFile( Filename, FilenameLoc, isAngled, FromDir, &CurDir, Includers, SearchPath, RelativePath, RequestingModule, SuggestedModule, IsMapped, - IsFrameworkFound, SkipCache, BuildSystemModule); + IsFrameworkFound, SkipCache, BuildSystemModule, OpenFile, CacheFailures); if (FE) { if (SuggestedModule && !LangOpts.AsmPreprocessor) HeaderInfo.getModuleMap().diagnoseHeaderInclusion( -- cgit v1.2.3