Skip to content

Commit 5ea78c4

Browse files
committed
[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
1 parent 1888dc9 commit 5ea78c4

File tree

12 files changed

+85
-61
lines changed

12 files changed

+85
-61
lines changed

clang/include/clang/Basic/FileEntry.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,23 @@ static_assert(
341341
OptionalFileEntryRefDegradesToFileEntryPtr>::value,
342342
"OptionalFileEntryRefDegradesToFileEntryPtr should be trivially copyable");
343343

344+
inline bool operator==(const FileEntry *LHS,
345+
const Optional<FileEntryRef> &RHS) {
346+
return LHS == (RHS ? &RHS->getFileEntry() : nullptr);
347+
}
348+
inline bool operator==(const Optional<FileEntryRef> &LHS,
349+
const FileEntry *RHS) {
350+
return (LHS ? &LHS->getFileEntry() : nullptr) == RHS;
351+
}
352+
inline bool operator!=(const FileEntry *LHS,
353+
const Optional<FileEntryRef> &RHS) {
354+
return !(LHS == RHS);
355+
}
356+
inline bool operator!=(const Optional<FileEntryRef> &LHS,
357+
const FileEntry *RHS) {
358+
return !(LHS == RHS);
359+
}
360+
344361
/// Cached information about one file (either on disk
345362
/// or in the virtual file system).
346363
///

clang/include/clang/Basic/SourceManager.h

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,9 @@ class alignas(8) ContentCache {
139139
/// It is possible for this to be NULL if the ContentCache encapsulates
140140
/// an imaginary text buffer.
141141
///
142-
/// FIXME: Turn this into a FileEntryRef and remove Filename.
143-
const FileEntry *OrigEntry;
142+
/// FIXME: Make non-optional using a virtual file as needed, remove \c
143+
/// Filename and use \c OrigEntry.getNameAsRequested() instead.
144+
OptionalFileEntryRefDegradesToFileEntryPtr OrigEntry;
144145

145146
/// References the file which the contents were actually loaded from.
146147
///
@@ -177,9 +178,13 @@ class alignas(8) ContentCache {
177178

178179
mutable unsigned IsBufferInvalid : 1;
179180

180-
ContentCache(const FileEntry *Ent = nullptr) : ContentCache(Ent, Ent) {}
181+
ContentCache()
182+
: OrigEntry(None), ContentsEntry(nullptr), BufferOverridden(false),
183+
IsFileVolatile(false), IsTransient(false), IsBufferInvalid(false) {}
184+
185+
ContentCache(FileEntryRef Ent) : ContentCache(Ent, Ent) {}
181186

182-
ContentCache(const FileEntry *Ent, const FileEntry *contentEnt)
187+
ContentCache(FileEntryRef Ent, const FileEntry *contentEnt)
183188
: OrigEntry(Ent), ContentsEntry(contentEnt), BufferOverridden(false),
184189
IsFileVolatile(false), IsTransient(false), IsBufferInvalid(false) {}
185190

@@ -660,7 +665,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
660665
struct OverriddenFilesInfoTy {
661666
/// Files that have been overridden with the contents from another
662667
/// file.
663-
llvm::DenseMap<const FileEntry *, const FileEntry *> OverriddenFiles;
668+
llvm::DenseMap<const FileEntry *, FileEntryRef> OverriddenFiles;
664669

665670
/// Files that were overridden with a memory buffer.
666671
llvm::DenseSet<const FileEntry *> OverriddenFilesWithBuffer;
@@ -978,8 +983,7 @@ class SourceManager : public RefCountedBase<SourceManager> {
978983
///
979984
/// \param NewFile the file whose contents will be used as the
980985
/// data instead of the contents of the given source file.
981-
void overrideFileContents(const FileEntry *SourceFile,
982-
const FileEntry *NewFile);
986+
void overrideFileContents(const FileEntry *SourceFile, FileEntryRef NewFile);
983987

984988
/// Returns true if the file contents have been overridden.
985989
bool isFileOverridden(const FileEntry *File) const {
@@ -1044,8 +1048,8 @@ class SourceManager : public RefCountedBase<SourceManager> {
10441048

10451049
/// Returns the FileEntryRef for the provided FileID.
10461050
Optional<FileEntryRef> getFileEntryRefForID(FileID FID) const {
1047-
if (auto *Entry = getFileEntryForID(FID))
1048-
return Entry->getLastRef();
1051+
if (auto *Entry = getSLocEntryForFile(FID))
1052+
return Entry->getFile().getContentCache().OrigEntry;
10491053
return None;
10501054
}
10511055

clang/include/clang/Lex/ModuleMap.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ class ModuleMap {
607607
///
608608
/// \returns The file entry for the module map file containing the given
609609
/// module, or nullptr if the module definition was inferred.
610-
const FileEntry *getContainingModuleMapFile(const Module *Module) const;
610+
Optional<FileEntryRef> getContainingModuleMapFile(const Module *Module) const;
611611

612612
/// Get the module map file that (along with the module name) uniquely
613613
/// identifies this module.
@@ -618,7 +618,7 @@ class ModuleMap {
618618
/// of inferred modules, returns the module map that allowed the inference
619619
/// (e.g. contained 'module *'). Otherwise, returns
620620
/// getContainingModuleMapFile().
621-
const FileEntry *getModuleMapFileForUniquing(const Module *M) const;
621+
Optional<FileEntryRef> getModuleMapFileForUniquing(const Module *M) const;
622622

623623
void setInferredModuleAllowedBy(Module *M, const FileEntry *ModMap);
624624

clang/lib/Basic/SourceManager.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,7 @@ ContentCache &SourceManager::getOrCreateContentCache(FileEntryRef FileEnt,
399399
if (OverriddenFilesInfo) {
400400
// If the file contents are overridden with contents from another file,
401401
// pass that file to ContentCache.
402-
llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator
403-
overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt);
402+
auto overI = OverriddenFilesInfo->OverriddenFiles.find(FileEnt);
404403
if (overI == OverriddenFilesInfo->OverriddenFiles.end())
405404
new (Entry) ContentCache(FileEnt);
406405
else
@@ -695,14 +694,18 @@ void SourceManager::overrideFileContents(
695694
}
696695

697696
void SourceManager::overrideFileContents(const FileEntry *SourceFile,
698-
const FileEntry *NewFile) {
699-
assert(SourceFile->getSize() == NewFile->getSize() &&
697+
FileEntryRef NewFile) {
698+
assert(SourceFile->getSize() == NewFile.getSize() &&
700699
"Different sizes, use the FileManager to create a virtual file with "
701700
"the correct size");
702701
assert(FileInfos.count(SourceFile) == 0 &&
703702
"This function should be called at the initialization stage, before "
704703
"any parsing occurs.");
705-
getOverriddenFilesInfo().OverriddenFiles[SourceFile] = NewFile;
704+
// FileEntryRef is not default-constructible.
705+
auto Pair = getOverriddenFilesInfo().OverriddenFiles.insert(
706+
std::make_pair(SourceFile, NewFile));
707+
if (!Pair.second)
708+
Pair.first->second = NewFile;
706709
}
707710

708711
Optional<FileEntryRef>

clang/lib/Frontend/CompilerInstance.cpp

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -423,15 +423,15 @@ static void InitializeFileRemapping(DiagnosticsEngine &Diags,
423423
// Remap files in the source manager (with other files).
424424
for (const auto &RF : InitOpts.RemappedFiles) {
425425
// Find the file that we're mapping to.
426-
auto ToFile = FileMgr.getFile(RF.second);
426+
Optional<FileEntryRef> ToFile = FileMgr.getOptionalFileRef(RF.second);
427427
if (!ToFile) {
428428
Diags.Report(diag::err_fe_remap_missing_to_file) << RF.first << RF.second;
429429
continue;
430430
}
431431

432432
// Create the file entry for the file that we're mapping from.
433433
const FileEntry *FromFile =
434-
FileMgr.getVirtualFile(RF.first, (*ToFile)->getSize(), 0);
434+
FileMgr.getVirtualFile(RF.first, ToFile->getSize(), 0);
435435
if (!FromFile) {
436436
Diags.Report(diag::err_fe_remap_missing_from_file) << RF.first;
437437
continue;
@@ -1278,19 +1278,17 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
12781278
Instance.getFrontendOpts().AllowPCMWithCompilerErrors;
12791279
}
12801280

1281-
static const FileEntry *getPublicModuleMap(const FileEntry *File,
1282-
FileManager &FileMgr) {
1283-
StringRef Filename = llvm::sys::path::filename(File->getName());
1284-
SmallString<128> PublicFilename(File->getDir()->getName());
1281+
static Optional<FileEntryRef> getPublicModuleMap(FileEntryRef File,
1282+
FileManager &FileMgr) {
1283+
StringRef Filename = llvm::sys::path::filename(File.getName());
1284+
SmallString<128> PublicFilename(File.getDir().getName());
12851285
if (Filename == "module_private.map")
12861286
llvm::sys::path::append(PublicFilename, "module.map");
12871287
else if (Filename == "module.private.modulemap")
12881288
llvm::sys::path::append(PublicFilename, "module.modulemap");
12891289
else
1290-
return nullptr;
1291-
if (auto FE = FileMgr.getFile(PublicFilename))
1292-
return *FE;
1293-
return nullptr;
1290+
return None;
1291+
return FileMgr.getOptionalFileRef(PublicFilename);
12941292
}
12951293

12961294
/// Compile a module file for the given module in a separate compiler instance,
@@ -1306,19 +1304,16 @@ static bool compileModule(CompilerInstance &ImportingInstance,
13061304
ModuleMap &ModMap
13071305
= ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
13081306
bool Result;
1309-
if (const FileEntry *ModuleMapFile =
1307+
if (Optional<FileEntryRef> ModuleMapFile =
13101308
ModMap.getContainingModuleMapFile(Module)) {
13111309
// Canonicalize compilation to start with the public module map. This is
13121310
// vital for submodules declarations in the private module maps to be
13131311
// correctly parsed when depending on a top level module in the public one.
1314-
if (const FileEntry *PublicMMFile = getPublicModuleMap(
1315-
ModuleMapFile, ImportingInstance.getFileManager()))
1312+
if (Optional<FileEntryRef> PublicMMFile = getPublicModuleMap(
1313+
*ModuleMapFile, ImportingInstance.getFileManager()))
13161314
ModuleMapFile = PublicMMFile;
13171315

1318-
// FIXME: Update header search to keep FileEntryRef rather than rely on
1319-
// getLastRef().
1320-
StringRef ModuleMapFilePath =
1321-
ModuleMapFile->getLastRef().getNameAsRequested();
1316+
StringRef ModuleMapFilePath = ModuleMapFile->getNameAsRequested();
13221317

13231318
// Use the module map where this module resides.
13241319
Result = compileModuleImpl(
@@ -1346,7 +1341,7 @@ static bool compileModule(CompilerInstance &ImportingInstance,
13461341
[&](CompilerInstance &Instance) {
13471342
std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer =
13481343
llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent);
1349-
ModuleMapFile = Instance.getFileManager().getVirtualFile(
1344+
const FileEntry *ModuleMapFile = Instance.getFileManager().getVirtualFile(
13501345
FakeModuleMapFile, InferredModuleMapContent.size(), 0);
13511346
Instance.getSourceManager().overrideFileContents(
13521347
ModuleMapFile, std::move(ModuleMapBuffer));

clang/lib/Lex/HeaderSearch.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,11 @@ void HeaderSearch::getHeaderMapFileNames(
170170
}
171171

172172
std::string HeaderSearch::getCachedModuleFileName(Module *Module) {
173-
const FileEntry *ModuleMap =
173+
Optional<FileEntryRef> ModuleMap =
174174
getModuleMap().getModuleMapFileForUniquing(Module);
175175
// The ModuleMap maybe a nullptr, when we load a cached C++ module without
176176
// *.modulemap file. In this case, just return an empty string.
177-
if (ModuleMap == nullptr)
177+
if (!ModuleMap)
178178
return {};
179179
return getCachedModuleFileName(Module->Name, ModuleMap->getName());
180180
}
@@ -211,7 +211,7 @@ std::string HeaderSearch::getPrebuiltModuleFileName(StringRef ModuleName,
211211
}
212212

213213
std::string HeaderSearch::getPrebuiltImplicitModuleFileName(Module *Module) {
214-
const FileEntry *ModuleMap =
214+
Optional<FileEntryRef> ModuleMap =
215215
getModuleMap().getModuleMapFileForUniquing(Module);
216216
StringRef ModuleName = Module->Name;
217217
StringRef ModuleMapPath = ModuleMap->getName();

clang/lib/Lex/ModuleMap.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File) {
609609
UmbrellaModule = UmbrellaModule->Parent;
610610

611611
if (UmbrellaModule->InferSubmodules) {
612-
const FileEntry *UmbrellaModuleMap =
612+
OptionalFileEntryRefDegradesToFileEntryPtr UmbrellaModuleMap =
613613
getModuleMapFileForUniquing(UmbrellaModule);
614614

615615
// Infer submodules for each of the directories we found between
@@ -1023,9 +1023,11 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
10231023
// If we're not allowed to infer a framework module, don't.
10241024
if (!canInfer)
10251025
return nullptr;
1026-
} else
1027-
ModuleMapFile = getModuleMapFileForUniquing(Parent);
1028-
1026+
} else {
1027+
OptionalFileEntryRefDegradesToFileEntryPtr ModuleMapRef =
1028+
getModuleMapFileForUniquing(Parent);
1029+
ModuleMapFile = ModuleMapRef;
1030+
}
10291031

10301032
// Look for an umbrella header.
10311033
SmallString<128> UmbrellaName = StringRef(FrameworkDir->getName());
@@ -1277,19 +1279,21 @@ void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
12771279
Mod->Headers[Module::HK_Excluded].push_back(std::move(Header));
12781280
}
12791281

1280-
const FileEntry *
1282+
Optional<FileEntryRef>
12811283
ModuleMap::getContainingModuleMapFile(const Module *Module) const {
12821284
if (Module->DefinitionLoc.isInvalid())
1283-
return nullptr;
1285+
return None;
12841286

1285-
return SourceMgr.getFileEntryForID(
1286-
SourceMgr.getFileID(Module->DefinitionLoc));
1287+
return SourceMgr.getFileEntryRefForID(
1288+
SourceMgr.getFileID(Module->DefinitionLoc));
12871289
}
12881290

1289-
const FileEntry *ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
1291+
Optional<FileEntryRef>
1292+
ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
12901293
if (M->IsInferred) {
12911294
assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
1292-
return InferredModuleAllowedBy.find(M)->second;
1295+
// FIXME: Update InferredModuleAllowedBy to use FileEntryRef.
1296+
return InferredModuleAllowedBy.find(M)->second->getLastRef();
12931297
}
12941298
return getContainingModuleMapFile(M);
12951299
}

clang/lib/Serialization/ASTReader.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3919,7 +3919,8 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F,
39193919
Module *M =
39203920
PP.getHeaderSearchInfo().lookupModule(F.ModuleName, F.ImportLoc);
39213921
auto &Map = PP.getHeaderSearchInfo().getModuleMap();
3922-
const FileEntry *ModMap = M ? Map.getModuleMapFileForUniquing(M) : nullptr;
3922+
Optional<FileEntryRef> ModMap =
3923+
M ? Map.getModuleMapFileForUniquing(M) : None;
39233924
// Don't emit module relocation error if we have -fno-validate-pch
39243925
if (!bool(PP.getPreprocessorOpts().DisablePCHOrModuleValidation &
39253926
DisableValidationForModuleKind::Module) &&

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,13 +193,13 @@ std::set<const FileEntry *> GetAllModuleMaps(const HeaderSearch &HS,
193193
auto *CurrentModule = ModulesToProcess.pop_back_val();
194194
ProcessedModules.insert(CurrentModule);
195195

196-
auto *ModuleMapFile =
196+
Optional<FileEntryRef> ModuleMapFile =
197197
HS.getModuleMap().getModuleMapFileForUniquing(CurrentModule);
198198
if (!ModuleMapFile) {
199199
continue;
200200
}
201201

202-
ModuleMaps.insert(ModuleMapFile);
202+
ModuleMaps.insert(*ModuleMapFile);
203203

204204
for (auto *ImportedModule : (CurrentModule)->Imports) {
205205
if (!ImportedModule ||

clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ void ModuleDepCollector::applyDiscoveredDependencies(CompilerInvocation &CI) {
227227
if (llvm::any_of(CI.getFrontendOpts().Inputs, needsModules)) {
228228
Preprocessor &PP = ScanInstance.getPreprocessor();
229229
if (Module *CurrentModule = PP.getCurrentModuleImplementation())
230-
if (const FileEntry *CurrentModuleMap =
230+
if (Optional<FileEntryRef> CurrentModuleMap =
231231
PP.getHeaderSearchInfo()
232232
.getModuleMap()
233233
.getModuleMapFileForUniquing(CurrentModule))
@@ -406,13 +406,13 @@ ModuleID ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
406406
MD.ImplicitModulePCMPath = std::string(M->getASTFile()->getName());
407407
MD.IsSystem = M->IsSystem;
408408

409-
const FileEntry *ModuleMap = MDC.ScanInstance.getPreprocessor()
410-
.getHeaderSearchInfo()
411-
.getModuleMap()
412-
.getModuleMapFileForUniquing(M);
409+
Optional<FileEntryRef> ModuleMap = MDC.ScanInstance.getPreprocessor()
410+
.getHeaderSearchInfo()
411+
.getModuleMap()
412+
.getModuleMapFileForUniquing(M);
413413

414414
if (ModuleMap) {
415-
StringRef Path = ModuleMap->tryGetRealPathName();
415+
StringRef Path = ModuleMap->getFileEntry().tryGetRealPathName();
416416
if (Path.empty())
417417
Path = ModuleMap->getName();
418418
MD.ClangModuleMapFile = std::string(Path);

clang/test/Modules/malformed.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
//
44
// RUN: rm -rf %t
55
// RUN: cd %S
6-
// 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
7-
// 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
8-
// 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
6+
// 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
7+
// 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
8+
// 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
99

1010
#define STR2(x) #x
1111
#define STR(x) STR2(x)

clang/tools/libclang/CIndexInclusionStack.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ void getInclusions(bool IsLocal, unsigned n, CXTranslationUnit TU,
5959

6060
// Callback to the client.
6161
// FIXME: We should have a function to construct CXFiles.
62-
CB(static_cast<CXFile>(
63-
const_cast<FileEntry *>(FI.getContentCache().OrigEntry)),
62+
CB(static_cast<CXFile>(const_cast<FileEntry *>(
63+
static_cast<const FileEntry *>(FI.getContentCache().OrigEntry))),
6464
InclusionStack.data(), InclusionStack.size(), clientData);
6565
}
6666
}

0 commit comments

Comments
 (0)