[clang] 6bbccc0 - [clang][modules] Adopt `FileEntryRef` in the `HeaderFileInfo` block in PCM files (#67383)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 28 09:28:07 PDT 2023
Author: Jan Svoboda
Date: 2023-09-28T09:28:02-07:00
New Revision: 6bbccc0bcb36689507ba98ef338527d43334c7e7
URL: https://github.com/llvm/llvm-project/commit/6bbccc0bcb36689507ba98ef338527d43334c7e7
DIFF: https://github.com/llvm/llvm-project/commit/6bbccc0bcb36689507ba98ef338527d43334c7e7.diff
LOG: [clang][modules] Adopt `FileEntryRef` in the `HeaderFileInfo` block in PCM files (#67383)
This patch adopts `FileEntryRef` in the `HeaderFileInfo`-writing part of
`ASTWriter`.
First, this patch removes the loop over
`FileManager::VirtualFileEntries`. It's redundant, since all virtual
file entries are also present in `SeenFileEntries` and thus already in
`UIDToFiles`.
Second, since we now no longer rely on
`FileEntry::getLastRef()`/`FileEntry::getName()`, this patch takes care
to establish which path gets used for each UID by picking the
`FileEntryRef` with the most "`<`" name (instead of just relying on the
`StringMap` iteration order).
Note that which `FileEntry`/`FileEntryRef` objects we pick for each UID
for serialization into the `llvm::OnDiskChainedHashTable` doesn't really
matter. The hash function only includes the file size and modification
time. The file name only plays role during resolution of hash
collisions, in which case it goes through `FileManager` and resolves to
a `FileEntry` that gets pointer-compared with the queried `FileEntry`.
(Reincarnation of [D143414](https://reviews.llvm.org/D143414) and
[D142780](https://reviews.llvm.org/D142780).)
Added:
Modified:
clang/include/clang/Basic/FileManager.h
clang/lib/Basic/FileManager.cpp
clang/lib/Serialization/ASTWriter.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/FileManager.h b/clang/include/clang/Basic/FileManager.h
index 115558bfeee4ed5..56cb093dd8c376f 100644
--- a/clang/include/clang/Basic/FileManager.h
+++ b/clang/include/clang/Basic/FileManager.h
@@ -311,9 +311,9 @@ class FileManager : public RefCountedBase<FileManager> {
bool makeAbsolutePath(SmallVectorImpl<char> &Path) const;
/// Produce an array mapping from the unique IDs assigned to each
- /// file to the corresponding FileEntry pointer.
- void GetUniqueIDMapping(
- SmallVectorImpl<const FileEntry *> &UIDToFiles) const;
+ /// file to the corresponding FileEntryRef.
+ void
+ GetUniqueIDMapping(SmallVectorImpl<OptionalFileEntryRef> &UIDToFiles) const;
/// Retrieve the canonical name for a given directory.
///
diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp
index c80fbfd7433f5be..d16626b10652136 100644
--- a/clang/lib/Basic/FileManager.cpp
+++ b/clang/lib/Basic/FileManager.cpp
@@ -612,24 +612,21 @@ FileManager::getNoncachedStatValue(StringRef Path,
}
void FileManager::GetUniqueIDMapping(
- SmallVectorImpl<const FileEntry *> &UIDToFiles) const {
+ SmallVectorImpl<OptionalFileEntryRef> &UIDToFiles) const {
UIDToFiles.clear();
UIDToFiles.resize(NextFileUID);
- // Map file entries
- for (llvm::StringMap<llvm::ErrorOr<FileEntryRef::MapValue>,
- llvm::BumpPtrAllocator>::const_iterator
- FE = SeenFileEntries.begin(),
- FEEnd = SeenFileEntries.end();
- FE != FEEnd; ++FE)
- if (llvm::ErrorOr<FileEntryRef::MapValue> Entry = FE->getValue()) {
- if (const auto *FE = Entry->V.dyn_cast<FileEntry *>())
- UIDToFiles[FE->getUID()] = FE;
- }
-
- // Map virtual file entries
- for (const auto &VFE : VirtualFileEntries)
- UIDToFiles[VFE->getUID()] = VFE;
+ for (const auto &Entry : SeenFileEntries) {
+ // Only return files that exist and are not redirected.
+ if (!Entry.getValue() || !Entry.getValue()->V.is<FileEntry *>())
+ continue;
+ FileEntryRef FE(Entry);
+ // Add this file if it's the first one with the UID, or if its name is
+ // better than the existing one.
+ OptionalFileEntryRef &ExistingFE = UIDToFiles[FE.getUID()];
+ if (!ExistingFE || FE.getName() < ExistingFE->getName())
+ ExistingFE = FE;
+ }
}
StringRef FileManager::getCanonicalName(DirectoryEntryRef Dir) {
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 95a9fc922f1948d..b94acccb93e2f08 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -167,23 +167,23 @@ std::set<const FileEntry *> GetAffectingModuleMaps(const Preprocessor &PP,
const HeaderSearch &HS = PP.getHeaderSearchInfo();
- SmallVector<const FileEntry *, 16> FilesByUID;
+ SmallVector<OptionalFileEntryRef, 16> FilesByUID;
HS.getFileMgr().GetUniqueIDMapping(FilesByUID);
if (FilesByUID.size() > HS.header_file_size())
FilesByUID.resize(HS.header_file_size());
for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) {
- const FileEntry *File = FilesByUID[UID];
+ OptionalFileEntryRef File = FilesByUID[UID];
if (!File)
continue;
const HeaderFileInfo *HFI =
- HS.getExistingFileInfo(File, /*WantExternal*/ false);
+ HS.getExistingFileInfo(*File, /*WantExternal*/ false);
if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
continue;
- for (const auto &KH : HS.findResolvedModulesForHeader(File)) {
+ for (const auto &KH : HS.findResolvedModulesForHeader(*File)) {
if (!KH.getModule())
continue;
ModulesToProcess.push_back(KH.getModule());
@@ -2003,14 +2003,14 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
}
}
- SmallVector<const FileEntry *, 16> FilesByUID;
+ SmallVector<OptionalFileEntryRef, 16> FilesByUID;
HS.getFileMgr().GetUniqueIDMapping(FilesByUID);
if (FilesByUID.size() > HS.header_file_size())
FilesByUID.resize(HS.header_file_size());
for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) {
- const FileEntry *File = FilesByUID[UID];
+ OptionalFileEntryRef File = FilesByUID[UID];
if (!File)
continue;
@@ -2021,7 +2021,7 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
// from a
diff erent module; in that case, we rely on the module(s)
// containing the header to provide this information.
const HeaderFileInfo *HFI =
- HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
+ HS.getExistingFileInfo(*File, /*WantExternal*/!Chain);
if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
continue;
@@ -2035,13 +2035,13 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
SavedStrings.push_back(Filename.data());
}
- bool Included = PP->alreadyIncluded(File);
+ bool Included = PP->alreadyIncluded(*File);
HeaderFileInfoTrait::key_type Key = {
- Filename, File->getSize(), getTimestampForOutput(File)
+ Filename, File->getSize(), getTimestampForOutput(*File)
};
HeaderFileInfoTrait::data_type Data = {
- *HFI, Included, HS.getModuleMap().findResolvedModulesForHeader(File), {}
+ *HFI, Included, HS.getModuleMap().findResolvedModulesForHeader(*File), {}
};
Generator.insert(Key, Data, GeneratorTrait);
++NumHeaderSearchEntries;
More information about the cfe-commits
mailing list