Skip to content

Commit ab6adca

Browse files
committed
[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`. (cherry picked from commit da1a16a)
1 parent 459ebb5 commit ab6adca

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
@@ -2307,6 +2307,8 @@ class ASTReader
23072307
/// Translate a FileID from another module file's FileID space into ours.
23082308
FileID TranslateFileID(ModuleFile &F, FileID FID) const {
23092309
assert(FID.ID >= 0 && "Reading non-local FileID.");
2310+
if (FID.isInvalid())
2311+
return FID;
23102312
return FileID::get(F.SLocEntryBaseID + FID.ID - 1);
23112313
}
23122314

clang/lib/Frontend/FrontendAction.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,6 @@ static Module *prepareToBuildModule(CompilerInstance &CI,
547547
}
548548
if (*OriginalModuleMap != CI.getSourceManager().getFileEntryRefForID(
549549
CI.getSourceManager().getMainFileID())) {
550-
M->IsInferred = true;
551550
auto FileCharacter =
552551
M->IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap;
553552
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
@@ -1106,8 +1104,7 @@ Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
11061104
Module *Result = new (ModulesAlloc.Allocate())
11071105
Module(ModuleConstructorTag{}, ModuleName, SourceLocation(), Parent,
11081106
/*IsFramework=*/true, /*IsExplicit=*/false, NumCreatedModules++);
1109-
InferredModuleAllowedBy[Result] = ModuleMapFID;
1110-
Result->IsInferred = true;
1107+
setInferredModuleAllowedBy(Result, ModuleMapFID);
11111108
if (!Parent) {
11121109
if (LangOpts.CurrentModule == ModuleName)
11131110
SourceModule = Result;
@@ -1354,7 +1351,7 @@ ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
13541351
}
13551352

13561353
void ModuleMap::setInferredModuleAllowedBy(Module *M, FileID ModMapFID) {
1357-
assert(M->IsInferred && "module not inferred");
1354+
M->IsInferred = true;
13581355
InferredModuleAllowedBy[M] = ModMapFID;
13591356
}
13601357

clang/lib/Serialization/ASTReader.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5821,6 +5821,7 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F,
58215821
bool IsSwiftInferImportAsMember = Record[Idx++];
58225822

58235823
SourceLocation DefinitionLoc = ReadSourceLocation(F, Record[Idx++]);
5824+
FileID InferredAllowedBy = ReadFileID(F, Record, Idx);
58245825
bool IsFramework = Record[Idx++];
58255826
bool IsExplicit = Record[Idx++];
58265827
bool IsSystem = Record[Idx++];
@@ -5842,8 +5843,6 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F,
58425843
ModMap.findOrCreateModule(Name, ParentModule, IsFramework, IsExplicit)
58435844
.first;
58445845

5845-
// FIXME: Call ModMap.setInferredModuleAllowedBy()
5846-
58475846
SubmoduleID GlobalIndex = GlobalID - NUM_PREDEF_SUBMODULE_IDS;
58485847
if (GlobalIndex >= SubmodulesLoaded.size() ||
58495848
SubmodulesLoaded[GlobalIndex])
@@ -5876,6 +5875,8 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F,
58765875
CurrentModule->DefinitionLoc = DefinitionLoc;
58775876
CurrentModule->Signature = F.Signature;
58785877
CurrentModule->IsFromModuleFile = true;
5878+
if (InferredAllowedBy.isValid())
5879+
ModMap.setInferredModuleAllowedBy(CurrentModule, InferredAllowedBy);
58795880
CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem;
58805881
CurrentModule->IsExternC = IsExternC;
58815882
CurrentModule->InferSubmodules = InferSubmodules;

clang/lib/Serialization/ASTWriter.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2927,6 +2927,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
29272927
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsSwiftInferIAM...
29282928

29292929
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Definition location
2930+
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // Inferred allowed by
29302931
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsFramework
29312932
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExplicit
29322933
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsSystem
@@ -3031,6 +3032,12 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
30313032
SourceLocationEncoding::RawLocEncoding DefinitionLoc =
30323033
getRawSourceLocationEncoding(getAdjustedLocation(Mod->DefinitionLoc));
30333034

3035+
ModuleMap &ModMap = PP->getHeaderSearchInfo().getModuleMap();
3036+
FileID UnadjustedInferredFID;
3037+
if (Mod->IsInferred)
3038+
UnadjustedInferredFID = ModMap.getModuleMapFileIDForUniquing(Mod);
3039+
int InferredFID = getAdjustedFileID(UnadjustedInferredFID).getOpaqueValue();
3040+
30343041
// Emit the definition of the block.
30353042
{
30363043
RecordData::value_type Record[] = {SUBMODULE_DEFINITION,
@@ -3044,6 +3051,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) {
30443051
Mod->IsSwiftInferImportAsMember,
30453052

30463053
DefinitionLoc,
3054+
(RecordData::value_type)InferredFID,
30473055
Mod->IsFramework,
30483056
Mod->IsExplicit,
30493057
Mod->IsSystem,

clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp

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

659-
OptionalFileEntryRef ModuleMap = ModMapInfo.getModuleMapFileForUniquing(M);
660-
661-
if (ModuleMap) {
659+
if (auto ModuleMap = ModMapInfo.getModuleMapFileForUniquing(M)) {
662660
SmallString<128> Path = ModuleMap->getNameAsRequested();
663661
ModMapInfo.canonicalizeModuleMapPath(Path);
664662
MD.ClangModuleMapFile = std::string(Path);
@@ -670,15 +668,13 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
670668
MDC.ScanInstance.getASTReader()->visitInputFileInfos(
671669
*MF, /*IncludeSystem=*/true,
672670
[&](const serialization::InputFileInfo &IFI, bool IsSystem) {
673-
// __inferred_module.map is the result of the way in which an implicit
674-
// module build handles inferred modules. It adds an overlay VFS with
675-
// this file in the proper directory and relies on the rest of Clang to
676-
// handle it like normal. With explicitly built modules we don't need
677-
// to play VFS tricks, so replace it with the correct module map.
678-
if (StringRef(IFI.Filename).ends_with("__inferred_module.map")) {
679-
MDC.addFileDep(MD, ModuleMap->getName());
671+
// The __inferred_module.map file is an insignificant implementation
672+
// detail of implicitly-built modules. The PCM will also report the
673+
// actual on-disk module map file that allowed inferring the module,
674+
// which is what we need for building the module explicitly
675+
// Let's ignore this file.
676+
if (StringRef(IFI.Filename).ends_with("__inferred_module.map"))
680677
return;
681-
}
682678
MDC.addFileDep(MD, IFI.Filename);
683679
});
684680

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)