[clang] 5ea78c4 - [clang] Update ModuleMap::getModuleMapFile* to use FileEntryRef
Ben Langmuir via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 5 13:14:14 PDT 2022
Author: Ben Langmuir
Date: 2022-10-05T13:12:43-07:00
New Revision: 5ea78c4113f8d2c8be24152f2dd0cadaea352c9d
URL: https://github.com/llvm/llvm-project/commit/5ea78c4113f8d2c8be24152f2dd0cadaea352c9d
DIFF: https://github.com/llvm/llvm-project/commit/5ea78c4113f8d2c8be24152f2dd0cadaea352c9d.diff
LOG: [clang] Update ModuleMap::getModuleMapFile* to use FileEntryRef
Update SourceManager::ContentCache::OrigEntry to keep the original
FileEntryRef, and use that to enable ModuleMap::getModuleMapFile* to
return the original FileEntryRef. This change should be NFC for
most users of SourceManager::ContentCache, but it could affect behaviour
for users of getNameAsRequested such as in compileModuleImpl. I have not
found a way to detect that difference without additional functional
changes, other than incidental cases like changes from / to \ on
Windows so there is no new test.
Differential Revision: https://reviews.llvm.org/D135220
Added:
Modified:
clang/include/clang/Basic/FileEntry.h
clang/include/clang/Basic/SourceManager.h
clang/include/clang/Lex/ModuleMap.h
clang/lib/Basic/SourceManager.cpp
clang/lib/Frontend/CompilerInstance.cpp
clang/lib/Lex/HeaderSearch.cpp
clang/lib/Lex/ModuleMap.cpp
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
clang/test/Modules/malformed.cpp
clang/tools/libclang/CIndexInclusionStack.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/FileEntry.h b/clang/include/clang/Basic/FileEntry.h
index d9b92a73a1d82..4f2d6436b333b 100644
--- a/clang/include/clang/Basic/FileEntry.h
+++ b/clang/include/clang/Basic/FileEntry.h
@@ -341,6 +341,23 @@ static_assert(
OptionalFileEntryRefDegradesToFileEntryPtr>::value,
"OptionalFileEntryRefDegradesToFileEntryPtr should be trivially copyable");
+inline bool operator==(const FileEntry *LHS,
+ const Optional<FileEntryRef> &RHS) {
+ return LHS == (RHS ? &RHS->getFileEntry() : nullptr);
+}
+inline bool operator==(const Optional<FileEntryRef> &LHS,
+ const FileEntry *RHS) {
+ return (LHS ? &LHS->getFileEntry() : nullptr) == RHS;
+}
+inline bool operator!=(const FileEntry *LHS,
+ const Optional<FileEntryRef> &RHS) {
+ return !(LHS == RHS);
+}
+inline bool operator!=(const Optional<FileEntryRef> &LHS,
+ const FileEntry *RHS) {
+ return !(LHS == RHS);
+}
+
/// Cached information about one file (either on disk
/// or in the virtual file system).
///
diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h
index 8a737d6b4b398..1e0743ecd8b6c 100644
--- a/clang/include/clang/Basic/SourceManager.h
+++ b/clang/include/clang/Basic/SourceManager.h
@@ -139,8 +139,9 @@ class alignas(8) ContentCache {
/// It is possible for this to be NULL if the ContentCache encapsulates
/// an imaginary text buffer.
///
- /// FIXME: Turn this into a FileEntryRef and remove Filename.
- const FileEntry *OrigEntry;
+ /// FIXME: Make non-optional using a virtual file as needed, remove \c
+ /// Filename and use \c OrigEntry.getNameAsRequested() instead.
+ OptionalFileEntryRefDegradesToFileEntryPtr OrigEntry;
/// References the file which the contents were actually loaded from.
///
@@ -177,9 +178,13 @@ class alignas(8) ContentCache {
mutable unsigned IsBufferInvalid : 1;
- ContentCache(const FileEntry *Ent = nullptr) : ContentCache(Ent, Ent) {}
+ ContentCache()
+ : OrigEntry(None), ContentsEntry(nullptr), BufferOverridden(false),
+ IsFileVolatile(false), IsTransient(false), IsBufferInvalid(false) {}
+
+ ContentCache(FileEntryRef Ent) : ContentCache(Ent, Ent) {}
- ContentCache(const FileEntry *Ent, const FileEntry *contentEnt)
+ ContentCache(FileEntryRef Ent, const FileEntry *contentEnt)
: OrigEntry(Ent), ContentsEntry(contentEnt), BufferOverridden(false),
IsFileVolatile(false), IsTransient(false), IsBufferInvalid(false) {}
@@ -660,7 +665,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
struct OverriddenFilesInfoTy {
/// Files that have been overridden with the contents from another
/// file.
- llvm::DenseMap<const FileEntry *, const FileEntry *> OverriddenFiles;
+ llvm::DenseMap<const FileEntry *, FileEntryRef> OverriddenFiles;
/// Files that were overridden with a memory buffer.
llvm::DenseSet<const FileEntry *> OverriddenFilesWithBuffer;
@@ -978,8 +983,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
///
/// \param NewFile the file whose contents will be used as the
/// data instead of the contents of the given source file.
- void overrideFileContents(const FileEntry *SourceFile,
- const FileEntry *NewFile);
+ void overrideFileContents(const FileEntry *SourceFile, FileEntryRef NewFile);
/// Returns true if the file contents have been overridden.
bool isFileOverridden(const FileEntry *File) const {
@@ -1044,8 +1048,8 @@ class SourceManager : public RefCountedBase<SourceManager> {
/// Returns the FileEntryRef for the provided FileID.
Optional<FileEntryRef> getFileEntryRefForID(FileID FID) const {
- if (auto *Entry = getFileEntryForID(FID))
- return Entry->getLastRef();
+ if (auto *Entry = getSLocEntryForFile(FID))
+ return Entry->getFile().getContentCache().OrigEntry;
return None;
}
diff --git a/clang/include/clang/Lex/ModuleMap.h b/clang/include/clang/Lex/ModuleMap.h
index 8fbe4a927c77b..1084b49b3534a 100644
--- a/clang/include/clang/Lex/ModuleMap.h
+++ b/clang/include/clang/Lex/ModuleMap.h
@@ -607,7 +607,7 @@ class ModuleMap {
///
/// \returns The file entry for the module map file containing the given
/// module, or nullptr if the module definition was inferred.
- const FileEntry *getContainingModuleMapFile(const Module *Module) const;
+ Optional<FileEntryRef> getContainingModuleMapFile(const Module *Module) const;
/// Get the module map file that (along with the module name) uniquely
/// identifies this module.
@@ -618,7 +618,7 @@ class ModuleMap {
/// of inferred modules, returns the module map that allowed the inference
/// (e.g. contained 'module *'). Otherwise, returns
/// getContainingModuleMapFile().
- const FileEntry *getModuleMapFileForUniquing(const Module *M) const;
+ Optional<FileEntryRef> getModuleMapFileForUniquing(const Module *M) const;
void setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap);
diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp
index 7131b50c75ac0..de217a95d3921 100644
--- a/clang/lib/Basic/SourceManager.cpp
+++ b/clang/lib/Basic/SourceManager.cpp
@@ -399,8 +399,7 @@ ContentCache &SourceManager::getOrCreateContentCache(FileEntryRef FileEnt,
if (OverriddenFilesInfo) {
// If the file contents are overridden with contents from another file,
// pass that file to ContentCache.
- llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator
- overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt);
+ auto overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt);
if (overI == OverriddenFilesInfo->OverriddenFiles.end())
new (Entry) ContentCache(FileEnt);
else
@@ -695,14 +694,18 @@ void SourceManager::overrideFileContents(
}
void SourceManager::overrideFileContents(const FileEntry *SourceFile,
- const FileEntry *NewFile) {
- assert(SourceFile->getSize() == NewFile->getSize() &&
+ FileEntryRef NewFile) {
+ assert(SourceFile->getSize() == NewFile.getSize() &&
"Different sizes, use the FileManager to create a virtual file with "
"the correct size");
assert(FileInfos.count(SourceFile) == 0 &&
"This function should be called at the initialization stage, before "
"any parsing occurs.");
- getOverriddenFilesInfo().OverriddenFiles[SourceFile] = NewFile;
+ // FileEntryRef is not default-constructible.
+ auto Pair = getOverriddenFilesInfo().OverriddenFiles.insert(
+ std::make_pair(SourceFile, NewFile));
+ if (!Pair.second)
+ Pair.first->second = NewFile;
}
Optional<FileEntryRef>
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 995c94bb6912b..46f97e08f4e41 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -423,7 +423,7 @@ static void InitializeFileRemapping(DiagnosticsEngine &Diags,
// Remap files in the source manager (with other files).
for (const auto &RF : InitOpts.RemappedFiles) {
// Find the file that we're mapping to.
- auto ToFile = FileMgr.getFile(RF.second);
+ Optional<FileEntryRef> ToFile = FileMgr.getOptionalFileRef(RF.second);
if (!ToFile) {
Diags.Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second;
continue;
@@ -431,7 +431,7 @@ static void InitializeFileRemapping(DiagnosticsEngine &Diags,
// Create the file entry for the file that we're mapping from.
const FileEntry *FromFile =
- FileMgr.getVirtualFile(RF.first, (*ToFile)->getSize(), 0);
+ FileMgr.getVirtualFile(RF.first, ToFile->getSize(), 0);
if (!FromFile) {
Diags.Report(diag::err_fe_remap_missing_from_file) << RF.first;
continue;
@@ -1278,19 +1278,17 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
Instance.getFrontendOpts().AllowPCMWithCompilerErrors;
}
-static const FileEntry *getPublicModuleMap(const FileEntry *File,
- FileManager &FileMgr) {
- StringRef Filename = llvm::sys::path::filename(File->getName());
- SmallString<128> PublicFilename(File->getDir()->getName());
+static Optional<FileEntryRef> getPublicModuleMap(FileEntryRef File,
+ FileManager &FileMgr) {
+ StringRef Filename = llvm::sys::path::filename(File.getName());
+ SmallString<128> PublicFilename(File.getDir().getName());
if (Filename == "module_private.map")
llvm::sys::path::append(PublicFilename, "module.map");
else if (Filename == "module.private.modulemap")
llvm::sys::path::append(PublicFilename, "module.modulemap");
else
- return nullptr;
- if (auto FE = FileMgr.getFile(PublicFilename))
- return *FE;
- return nullptr;
+ return None;
+ return FileMgr.getOptionalFileRef(PublicFilename);
}
/// Compile a module file for the given module in a separate compiler instance,
@@ -1306,19 +1304,16 @@ static bool compileModule(CompilerInstance &ImportingInstance,
ModuleMap &ModMap
= ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
bool Result;
- if (const FileEntry *ModuleMapFile =
+ if (Optional<FileEntryRef> ModuleMapFile =
ModMap.getContainingModuleMapFile(Module)) {
// Canonicalize compilation to start with the public module map. This is
// vital for submodules declarations in the private module maps to be
// correctly parsed when depending on a top level module in the public one.
- if (const FileEntry *PublicMMFile = getPublicModuleMap(
- ModuleMapFile, ImportingInstance.getFileManager()))
+ if (Optional<FileEntryRef> PublicMMFile = getPublicModuleMap(
+ *ModuleMapFile, ImportingInstance.getFileManager()))
ModuleMapFile = PublicMMFile;
- // FIXME: Update header search to keep FileEntryRef rather than rely on
- // getLastRef().
- StringRef ModuleMapFilePath =
- ModuleMapFile->getLastRef().getNameAsRequested();
+ StringRef ModuleMapFilePath = ModuleMapFile->getNameAsRequested();
// Use the module map where this module resides.
Result = compileModuleImpl(
@@ -1346,7 +1341,7 @@ static bool compileModule(CompilerInstance &ImportingInstance,
[&](CompilerInstance &Instance) {
std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer =
llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent);
- ModuleMapFile = Instance.getFileManager().getVirtualFile(
+ const FileEntry *ModuleMapFile = Instance.getFileManager().getVirtualFile(
FakeModuleMapFile, InferredModuleMapContent.size(), 0);
Instance.getSourceManager().overrideFileContents(
ModuleMapFile, std::move(ModuleMapBuffer));
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index 029be1ed09b50..99596b1378ba1 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -170,11 +170,11 @@ void HeaderSearch::getHeaderMapFileNames(
}
std::string HeaderSearch::getCachedModuleFileName(Module *Module) {
- const FileEntry *ModuleMap =
+ Optional<FileEntryRef> ModuleMap =
getModuleMap().getModuleMapFileForUniquing(Module);
// The ModuleMap maybe a nullptr, when we load a cached C++ module without
// *.modulemap file. In this case, just return an empty string.
- if (ModuleMap == nullptr)
+ if (!ModuleMap)
return {};
return getCachedModuleFileName(Module->Name, ModuleMap->getName());
}
@@ -211,7 +211,7 @@ std::string HeaderSearch::getPrebuiltModuleFileName(StringRef ModuleName,
}
std::string HeaderSearch::getPrebuiltImplicitModuleFileName(Module *Module) {
- const FileEntry *ModuleMap =
+ Optional<FileEntryRef> ModuleMap =
getModuleMap().getModuleMapFileForUniquing(Module);
StringRef ModuleName = Module->Name;
StringRef ModuleMapPath = ModuleMap->getName();
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index 174d639ac1f90..dbb81dc0d1478 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -609,7 +609,7 @@ ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
UmbrellaModule = UmbrellaModule->Parent;
if (UmbrellaModule->InferSubmodules) {
- const FileEntry *UmbrellaModuleMap =
+ OptionalFileEntryRefDegradesToFileEntryPtr UmbrellaModuleMap =
getModuleMapFileForUniquing(UmbrellaModule);
// Infer submodules for each of the directories we found between
@@ -1023,9 +1023,11 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
// If we're not allowed to infer a framework module, don't.
if (!canInfer)
return nullptr;
- } else
- ModuleMapFile = getModuleMapFileForUniquing(Parent);
-
+ } else {
+ OptionalFileEntryRefDegradesToFileEntryPtr ModuleMapRef =
+ getModuleMapFileForUniquing(Parent);
+ ModuleMapFile = ModuleMapRef;
+ }
// Look for an umbrella header.
SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
@@ -1277,19 +1279,21 @@ void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
}
-const FileEntry *
+Optional<FileEntryRef>
ModuleMap::getContainingModuleMapFile(const Module *Module) const {
if (Module->DefinitionLoc.isInvalid())
- return nullptr;
+ return None;
- return SourceMgr.getFileEntryForID(
- SourceMgr.getFileID(Module->DefinitionLoc));
+ return SourceMgr.getFileEntryRefForID(
+ SourceMgr.getFileID(Module->DefinitionLoc));
}
-const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
+Optional<FileEntryRef>
+ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
if (M->IsInferred) {
assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
- return InferredModuleAllowedBy.find(M)->second;
+ // FIXME: Update InferredModuleAllowedBy to use FileEntryRef.
+ return InferredModuleAllowedBy.find(M)->second->getLastRef();
}
return getContainingModuleMapFile(M);
}
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 7f2bee17bdfc4..35d7055f8530b 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -3919,7 +3919,8 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F,
Module *M =
PP.getHeaderSearchInfo().lookupModule(F.ModuleName, F.ImportLoc);
auto &Map = PP.getHeaderSearchInfo().getModuleMap();
- const FileEntry *ModMap = M ? Map.getModuleMapFileForUniquing(M) : nullptr;
+ Optional<FileEntryRef> ModMap =
+ M ? Map.getModuleMapFileForUniquing(M) : None;
// Don't emit module relocation error if we have -fno-validate-pch
if (!bool(PP.getPreprocessorOpts().DisablePCHOrModuleValidation &
DisableValidationForModuleKind::Module) &&
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index c9c94d453f113..7bd6142fcf2d0 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -193,13 +193,13 @@ std::set<const FileEntry *> GetAllModuleMaps(const HeaderSearch &HS,
auto *CurrentModule = ModulesToProcess.pop_back_val();
ProcessedModules.insert(CurrentModule);
- auto *ModuleMapFile =
+ Optional<FileEntryRef> ModuleMapFile =
HS.getModuleMap().getModuleMapFileForUniquing(CurrentModule);
if (!ModuleMapFile) {
continue;
}
- ModuleMaps.insert(ModuleMapFile);
+ ModuleMaps.insert(*ModuleMapFile);
for (auto *ImportedModule : (CurrentModule)->Imports) {
if (!ImportedModule ||
diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
index 2da149c0afcce..ffb60f17e930e 100644
--- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
+++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
@@ -227,7 +227,7 @@ void ModuleDepCollector::applyDiscoveredDependencies(CompilerInvocation &CI) {
if (llvm::any_of(CI.getFrontendOpts().Inputs, needsModules)) {
Preprocessor &PP = ScanInstance.getPreprocessor();
if (Module *CurrentModule = PP.getCurrentModuleImplementation())
- if (const FileEntry *CurrentModuleMap =
+ if (Optional<FileEntryRef> CurrentModuleMap =
PP.getHeaderSearchInfo()
.getModuleMap()
.getModuleMapFileForUniquing(CurrentModule))
@@ -406,13 +406,13 @@ ModuleID ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
MD.ImplicitModulePCMPath = std::string(M->getASTFile()->getName());
MD.IsSystem = M->IsSystem;
- const FileEntry *ModuleMap = MDC.ScanInstance.getPreprocessor()
- .getHeaderSearchInfo()
- .getModuleMap()
- .getModuleMapFileForUniquing(M);
+ Optional<FileEntryRef> ModuleMap = MDC.ScanInstance.getPreprocessor()
+ .getHeaderSearchInfo()
+ .getModuleMap()
+ .getModuleMapFileForUniquing(M);
if (ModuleMap) {
- StringRef Path = ModuleMap->tryGetRealPathName();
+ StringRef Path = ModuleMap->getFileEntry().tryGetRealPathName();
if (Path.empty())
Path = ModuleMap->getName();
MD.ClangModuleMapFile = std::string(Path);
diff --git a/clang/test/Modules/malformed.cpp b/clang/test/Modules/malformed.cpp
index 040361c9eeb8e..54bdf5236e781 100644
--- a/clang/test/Modules/malformed.cpp
+++ b/clang/test/Modules/malformed.cpp
@@ -3,9 +3,9 @@
//
// RUN: rm -rf %t
// RUN: cd %S
-// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I Inputs/malformed -DHEADER="a1.h" %s 2>&1 | FileCheck %s --check-prefix=CHECK-A
-// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I Inputs/malformed -DHEADER="b1.h" %s 2>&1 | FileCheck %s --check-prefix=CHECK-B
-// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I Inputs/malformed -DHEADER="c.h" malformed.cpp 2>&1 | FileCheck %s --check-prefix=CHECK-C
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I Inputs/malformed -DHEADER="a1.h" %s 2>&1 | sed 's:\\\\\?:/:g' | FileCheck %s --check-prefix=CHECK-A
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I Inputs/malformed -DHEADER="b1.h" %s 2>&1 | sed 's:\\\\\?:/:g' | FileCheck %s --check-prefix=CHECK-B
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I Inputs/malformed -DHEADER="c.h" malformed.cpp 2>&1 | sed 's:\\\\\?:/:g' | FileCheck %s --check-prefix=CHECK-C
#define STR2(x) #x
#define STR(x) STR2(x)
diff --git a/clang/tools/libclang/CIndexInclusionStack.cpp b/clang/tools/libclang/CIndexInclusionStack.cpp
index 3e05cff12c484..9cb9e18401f0c 100644
--- a/clang/tools/libclang/CIndexInclusionStack.cpp
+++ b/clang/tools/libclang/CIndexInclusionStack.cpp
@@ -59,8 +59,8 @@ void getInclusions(bool IsLocal, unsigned n, CXTranslationUnit TU,
// Callback to the client.
// FIXME: We should have a function to construct CXFiles.
- CB(static_cast<CXFile>(
- const_cast<FileEntry *>(FI.getContentCache().OrigEntry)),
+ CB(static_cast<CXFile>(const_cast<FileEntry *>(
+ static_cast<const FileEntry *>(FI.getContentCache().OrigEntry))),
InclusionStack.data(), InclusionStack.size(), clientData);
}
}
More information about the cfe-commits
mailing list