Skip to content

Commit da1a16a

Browse files
authored
[clang][modules] Preserve the module map that allowed inferring (llvm#113389)
With inferred modules, the dependency scanner takes care to replace the fake "__inferred_module.map" path with the file that allowed the module to be inferred. However, this only worked when such a module was imported directly in the TU. Whenever such module got loaded transitively, the scanner would fail to perform the replacement. This is caused by the fact that PCM files are lossy and drop this information. This patch makes sure that PCMs include this file for each submodule (in the `SUBMODULE_DEFINITION` record), fixes one existing test with an incorrect assertion, and does a little drive-by refactoring of `ModuleMap`.
1 parent 19c0a74 commit da1a16a

File tree

8 files changed

+29
-27
lines changed

8 files changed

+29
-27
lines changed

clang/include/clang/Serialization/ASTBitCodes.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ namespace serialization {
4444
/// Version 4 of AST files also requires that the version control branch and
4545
/// revision match exactly, since there is no backward compatibility of
4646
/// AST files at this time.
47-
const unsigned VERSION_MAJOR = 31;
47+
const unsigned VERSION_MAJOR = 32;
4848

4949
/// AST file minor version number supported by this version of
5050
/// Clang.
@@ -54,7 +54,7 @@ const unsigned VERSION_MAJOR = 31;
5454
/// for the previous version could still support reading the new
5555
/// version by ignoring new kinds of subblocks), this number
5656
/// should be increased.
57-
const unsigned VERSION_MINOR = 1;
57+
const unsigned VERSION_MINOR = 0;
5858

5959
/// An ID number that refers to an identifier in an AST file.
6060
///

clang/include/clang/Serialization/ASTReader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2335,6 +2335,8 @@ class ASTReader
23352335
/// Translate a FileID from another module file's FileID space into ours.
23362336
FileID TranslateFileID(ModuleFile &F, FileID FID) const {
23372337
assert(FID.ID >= 0 && "Reading non-local FileID.");
2338+
if (FID.isInvalid())
2339+
return FID;
23382340
return FileID::get(F.SLocEntryBaseID + FID.ID - 1);
23392341
}
23402342

clang/lib/Frontend/FrontendAction.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,6 @@ static Module *prepareToBuildModule(CompilerInstance &CI,
534534
}
535535
if (*OriginalModuleMap != CI.getSourceManager().getFileEntryRefForID(
536536
CI.getSourceManager().getMainFileID())) {
537-
M->IsInferred = true;
538537
auto FileCharacter =
539538
M->IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap;
540539
FileID OriginalModuleMapFID = CI.getSourceManager().getOrCreateFileID(

clang/lib/Lex/ModuleMap.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -657,8 +657,7 @@ ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File) {
657657
llvm::sys::path::stem(SkippedDir.getName()), NameBuf);
658658
Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
659659
Explicit).first;
660-
InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
661-
Result->IsInferred = true;
660+
setInferredModuleAllowedBy(Result, UmbrellaModuleMap);
662661

663662
// Associate the module and the directory.
664663
UmbrellaDirs[SkippedDir] = Result;
@@ -675,8 +674,7 @@ ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File) {
675674
llvm::sys::path::stem(File.getName()), NameBuf);
676675
Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
677676
Explicit).first;
678-
InferredModuleAllowedBy[Result] = UmbrellaModuleMap;
679-
Result->IsInferred = true;
677+
setInferredModuleAllowedBy(Result, UmbrellaModuleMap);
680678
Result->addTopHeader(File);
681679

682680
// If inferred submodules export everything they import, add a
@@ -1097,8 +1095,7 @@ Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
10971095
Module *Result = new (ModulesAlloc.Allocate())
10981096
Module(ModuleConstructorTag{}, ModuleName, SourceLocation(), Parent,
10991097
/*IsFramework=*/true, /*IsExplicit=*/false, NumCreatedModules++);
1100-
InferredModuleAllowedBy[Result] = ModuleMapFID;
1101-
Result->IsInferred = true;
1098+
setInferredModuleAllowedBy(Result, ModuleMapFID);
11021099
if (!Parent) {
11031100
if (LangOpts.CurrentModule == ModuleName)
11041101
SourceModule = Result;
@@ -1346,7 +1343,7 @@ ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
13461343
}
13471344

13481345
void ModuleMap::setInferredModuleAllowedBy(Module *M, FileID ModMapFID) {
1349-
assert(M->IsInferred && "module not inferred");
1346+
M->IsInferred = true;
13501347
InferredModuleAllowedBy[M] = ModMapFID;
13511348
}
13521349

clang/lib/Serialization/ASTReader.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5813,6 +5813,7 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F,
58135813
SubmoduleID Parent = getGlobalSubmoduleID(F, Record[Idx++]);
58145814
Module::ModuleKind Kind = (Module::ModuleKind)Record[Idx++];
58155815
SourceLocation DefinitionLoc = ReadSourceLocation(F, Record[Idx++]);
5816+
FileID InferredAllowedBy = ReadFileID(F, Record, Idx);
58165817
bool IsFramework = Record[Idx++];
58175818
bool IsExplicit = Record[Idx++];
58185819
bool IsSystem = Record[Idx++];
@@ -5834,8 +5835,6 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F,
58345835
ModMap.findOrCreateModule(Name, ParentModule, IsFramework, IsExplicit)
58355836
.first;
58365837

5837-
// FIXME: Call ModMap.setInferredModuleAllowedBy()
5838-
58395838
SubmoduleID GlobalIndex = GlobalID - NUM_PREDEF_SUBMODULE_IDS;
58405839
if (GlobalIndex >= SubmodulesLoaded.size() ||
58415840
SubmodulesLoaded[GlobalIndex])
@@ -5866,6 +5865,8 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F,
58665865
CurrentModule->DefinitionLoc = DefinitionLoc;
58675866
CurrentModule->Signature = F.Signature;
58685867
CurrentModule->IsFromModuleFile = true;
5868+
if (InferredAllowedBy.isValid())
5869+
ModMap.setInferredModuleAllowedBy(CurrentModule, InferredAllowedBy);
58695870
CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem;
58705871
CurrentModule->IsExternC = IsExternC;
58715872
CurrentModule->InferSubmodules = InferSubmodules;

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2914,6 +2914,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
29142914
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Parent
29152915
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // Kind
29162916
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Definition location
2917+
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // Inferred allowed by
29172918
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework
29182919
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExplicit
29192920
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsSystem
@@ -3018,13 +3019,20 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
30183019
SourceLocationEncoding::RawLocEncoding DefinitionLoc =
30193020
getRawSourceLocationEncoding(getAdjustedLocation(Mod->DefinitionLoc));
30203021

3022+
ModuleMap &ModMap = PP->getHeaderSearchInfo().getModuleMap();
3023+
FileID UnadjustedInferredFID;
3024+
if (Mod->IsInferred)
3025+
UnadjustedInferredFID = ModMap.getModuleMapFileIDForUniquing(Mod);
3026+
int InferredFID = getAdjustedFileID(UnadjustedInferredFID).getOpaqueValue();
3027+
30213028
// Emit the definition of the block.
30223029
{
30233030
RecordData::value_type Record[] = {SUBMODULE_DEFINITION,
30243031
ID,
30253032
ParentID,
30263033
(RecordData::value_type)Mod->Kind,
30273034
DefinitionLoc,
3035+
(RecordData::value_type)InferredFID,
30283036
Mod->IsFramework,
30293037
Mod->IsExplicit,
30303038
Mod->IsSystem,

clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -587,9 +587,7 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
587587
ModuleMap &ModMapInfo =
588588
MDC.ScanInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
589589

590-
OptionalFileEntryRef ModuleMap = ModMapInfo.getModuleMapFileForUniquing(M);
591-
592-
if (ModuleMap) {
590+
if (auto ModuleMap = ModMapInfo.getModuleMapFileForUniquing(M)) {
593591
SmallString<128> Path = ModuleMap->getNameAsRequested();
594592
ModMapInfo.canonicalizeModuleMapPath(Path);
595593
MD.ClangModuleMapFile = std::string(Path);
@@ -601,15 +599,13 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
601599
MDC.ScanInstance.getASTReader()->visitInputFileInfos(
602600
*MF, /*IncludeSystem=*/true,
603601
[&](const serialization::InputFileInfo &IFI, bool IsSystem) {
604-
// __inferred_module.map is the result of the way in which an implicit
605-
// module build handles inferred modules. It adds an overlay VFS with
606-
// this file in the proper directory and relies on the rest of Clang to
607-
// handle it like normal. With explicitly built modules we don't need
608-
// to play VFS tricks, so replace it with the correct module map.
609-
if (StringRef(IFI.Filename).ends_with("__inferred_module.map")) {
610-
MDC.addFileDep(MD, ModuleMap->getName());
602+
// The __inferred_module.map file is an insignificant implementation
603+
// detail of implicitly-built modules. The PCM will also report the
604+
// actual on-disk module map file that allowed inferring the module,
605+
// which is what we need for building the module explicitly
606+
// Let's ignore this file.
607+
if (StringRef(IFI.Filename).ends_with("__inferred_module.map"))
611608
return;
612-
}
613609
MDC.addFileDep(MD, IFI.Filename);
614610
});
615611

clang/test/ClangScanDeps/link-libraries.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,13 @@ module transitive {
3939
// CHECK-NEXT: "modules": [
4040
// CHECK-NEXT: {
4141
// CHECK-NEXT: "clang-module-deps": [],
42-
// CHECK-NEXT: "clang-modulemap-file": "{{.*}}/__inferred_module.map",
42+
// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/Inputs/frameworks/module.modulemap",
4343
// CHECK-NEXT: "command-line": [
4444
// CHECK: ],
4545
// CHECK-NEXT: "context-hash": "{{.*}}",
4646
// CHECK-NEXT: "file-deps": [
47-
// CHECK-NEXT: "{{.*}}/Framework.h"
48-
// CHECK-NEXT: "{{.*}}/__inferred_module.map"
49-
// CHECK-NEXT: "{{.*}}/module.modulemap"
47+
// CHECK-NEXT: "[[PREFIX]]/Inputs/frameworks/Framework.framework/Headers/Framework.h"
48+
// CHECK-NEXT: "[[PREFIX]]/Inputs/frameworks/module.modulemap"
5049
// CHECK-NEXT: ],
5150
// CHECK-NEXT: "link-libraries": [
5251
// CHECK-NEXT: {

0 commit comments

Comments
 (0)