Skip to content

Commit 6bbccc0

Browse files
authored
[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).)
1 parent 7485d36 commit 6bbccc0

File tree

3 files changed

+25
-28
lines changed

3 files changed

+25
-28
lines changed

clang/include/clang/Basic/FileManager.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,9 +311,9 @@ class FileManager : public RefCountedBase<FileManager> {
311311
bool makeAbsolutePath(SmallVectorImpl<char> &Path) const;
312312

313313
/// Produce an array mapping from the unique IDs assigned to each
314-
/// file to the corresponding FileEntry pointer.
315-
void GetUniqueIDMapping(
316-
SmallVectorImpl<const FileEntry *> &UIDToFiles) const;
314+
/// file to the corresponding FileEntryRef.
315+
void
316+
GetUniqueIDMapping(SmallVectorImpl<OptionalFileEntryRef> &UIDToFiles) const;
317317

318318
/// Retrieve the canonical name for a given directory.
319319
///

clang/lib/Basic/FileManager.cpp

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -612,24 +612,21 @@ FileManager::getNoncachedStatValue(StringRef Path,
612612
}
613613

614614
void FileManager::GetUniqueIDMapping(
615-
SmallVectorImpl<const FileEntry *> &UIDToFiles) const {
615+
SmallVectorImpl<OptionalFileEntryRef> &UIDToFiles) const {
616616
UIDToFiles.clear();
617617
UIDToFiles.resize(NextFileUID);
618618

619-
// Map file entries
620-
for (llvm::StringMap<llvm::ErrorOr<FileEntryRef::MapValue>,
621-
llvm::BumpPtrAllocator>::const_iterator
622-
FE = SeenFileEntries.begin(),
623-
FEEnd = SeenFileEntries.end();
624-
FE != FEEnd; ++FE)
625-
if (llvm::ErrorOr<FileEntryRef::MapValue> Entry = FE->getValue()) {
626-
if (const auto *FE = Entry->V.dyn_cast<FileEntry *>())
627-
UIDToFiles[FE->getUID()] = FE;
628-
}
629-
630-
// Map virtual file entries
631-
for (const auto &VFE : VirtualFileEntries)
632-
UIDToFiles[VFE->getUID()] = VFE;
619+
for (const auto &Entry : SeenFileEntries) {
620+
// Only return files that exist and are not redirected.
621+
if (!Entry.getValue() || !Entry.getValue()->V.is<FileEntry *>())
622+
continue;
623+
FileEntryRef FE(Entry);
624+
// Add this file if it's the first one with the UID, or if its name is
625+
// better than the existing one.
626+
OptionalFileEntryRef &ExistingFE = UIDToFiles[FE.getUID()];
627+
if (!ExistingFE || FE.getName() < ExistingFE->getName())
628+
ExistingFE = FE;
629+
}
633630
}
634631

635632
StringRef FileManager::getCanonicalName(DirectoryEntryRef Dir) {

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -167,23 +167,23 @@ std::set<const FileEntry *> GetAffectingModuleMaps(const Preprocessor &PP,
167167

168168
const HeaderSearch &HS = PP.getHeaderSearchInfo();
169169

170-
SmallVector<const FileEntry *, 16> FilesByUID;
170+
SmallVector<OptionalFileEntryRef, 16> FilesByUID;
171171
HS.getFileMgr().GetUniqueIDMapping(FilesByUID);
172172

173173
if (FilesByUID.size() > HS.header_file_size())
174174
FilesByUID.resize(HS.header_file_size());
175175

176176
for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) {
177-
const FileEntry *File = FilesByUID[UID];
177+
OptionalFileEntryRef File = FilesByUID[UID];
178178
if (!File)
179179
continue;
180180

181181
const HeaderFileInfo *HFI =
182-
HS.getExistingFileInfo(File, /*WantExternal*/ false);
182+
HS.getExistingFileInfo(*File, /*WantExternal*/ false);
183183
if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
184184
continue;
185185

186-
for (const auto &KH : HS.findResolvedModulesForHeader(File)) {
186+
for (const auto &KH : HS.findResolvedModulesForHeader(*File)) {
187187
if (!KH.getModule())
188188
continue;
189189
ModulesToProcess.push_back(KH.getModule());
@@ -2003,14 +2003,14 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
20032003
}
20042004
}
20052005

2006-
SmallVector<const FileEntry *, 16> FilesByUID;
2006+
SmallVector<OptionalFileEntryRef, 16> FilesByUID;
20072007
HS.getFileMgr().GetUniqueIDMapping(FilesByUID);
20082008

20092009
if (FilesByUID.size() > HS.header_file_size())
20102010
FilesByUID.resize(HS.header_file_size());
20112011

20122012
for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) {
2013-
const FileEntry *File = FilesByUID[UID];
2013+
OptionalFileEntryRef File = FilesByUID[UID];
20142014
if (!File)
20152015
continue;
20162016

@@ -2021,7 +2021,7 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
20212021
// from a different module; in that case, we rely on the module(s)
20222022
// containing the header to provide this information.
20232023
const HeaderFileInfo *HFI =
2024-
HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
2024+
HS.getExistingFileInfo(*File, /*WantExternal*/!Chain);
20252025
if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
20262026
continue;
20272027

@@ -2035,13 +2035,13 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
20352035
SavedStrings.push_back(Filename.data());
20362036
}
20372037

2038-
bool Included = PP->alreadyIncluded(File);
2038+
bool Included = PP->alreadyIncluded(*File);
20392039

20402040
HeaderFileInfoTrait::key_type Key = {
2041-
Filename, File->getSize(), getTimestampForOutput(File)
2041+
Filename, File->getSize(), getTimestampForOutput(*File)
20422042
};
20432043
HeaderFileInfoTrait::data_type Data = {
2044-
*HFI, Included, HS.getModuleMap().findResolvedModulesForHeader(File), {}
2044+
*HFI, Included, HS.getModuleMap().findResolvedModulesForHeader(*File), {}
20452045
};
20462046
Generator.insert(Key, Data, GeneratorTrait);
20472047
++NumHeaderSearchEntries;

0 commit comments

Comments
 (0)