jansvoboda11 created this revision. jansvoboda11 added reviewers: Bigcheese, vsapsai. Herald added a subscriber: ributzka. Herald added a project: All. jansvoboda11 requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
With this patch, we mark module maps that include an affecting `extern` module map as also affecting. This is a generalization of D137197 <https://reviews.llvm.org/D137197>: now we don't require the importing module map to describe parent of the extern module. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D137206 Files: clang/lib/Serialization/ASTWriter.cpp clang/test/ClangScanDeps/modules-extern-unrelated.m
Index: clang/test/ClangScanDeps/modules-extern-unrelated.m =================================================================== --- /dev/null +++ clang/test/ClangScanDeps/modules-extern-unrelated.m @@ -0,0 +1,135 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t + +//--- tu.m +@import zeroth; + +//--- zeroth/module.modulemap +module zeroth { header "zeroth.h" } +//--- zeroth/zeroth.h +@import first; +#include "second.h" + +//--- first/module.modulemap +module first {} +module first_other { header "first_other.h" } +//--- first/first_other.h + +//--- second/module.modulemap +extern module second "second.modulemap" +//--- second/second.modulemap +module second { header "second.h" } +//--- second/second.h +#include "first_other.h" + +//--- cdb.json.template +[{ + "directory": "DIR", + "file": "DIR/tu.m", + "command": "clang -fmodules -fmodules-cache-path=DIR/cache -I DIR/zeroth -I DIR/first -I DIR/second -c DIR/tu.m -o DIR/tu.o" +}] + +// RUN: sed -e "s|DIR|%/t|g" -e "s|INPUTS|%/S/Inputs|g" %t/cdb.json.template > %t/cdb.json +// RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-full > %t/result.json +// RUN: cat %t/result.json | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t + +// CHECK: { +// CHECK-NEXT: "modules": [ +// CHECK-NEXT: { +// CHECK-NEXT: "clang-module-deps": [], +// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/first/module.modulemap", +// CHECK-NEXT: "command-line": [ +// CHECK: ], +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/first/module.modulemap" +// CHECK-NEXT: ], +// CHECK-NEXT: "name": "first" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "clang-module-deps": [], +// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/first/module.modulemap", +// CHECK-NEXT: "command-line": [ +// CHECK: ], +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/first/first_other.h", +// CHECK-NEXT: "[[PREFIX]]/first/module.modulemap" +// CHECK-NEXT: ], +// CHECK-NEXT: "name": "first_other" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "module-name": "first_other" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/second/second.modulemap", +// CHECK-NEXT: "command-line": [ +// CHECK: ], +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/first/module.modulemap", +// CHECK-NEXT: "[[PREFIX]]/second/second.h", +// CHECK-NEXT: "[[PREFIX]]/second/second.modulemap" +// CHECK-NEXT: ], +// CHECK-NEXT: "name": "second" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "module-name": "first" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "module-name": "second" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "clang-modulemap-file": "[[PREFIX]]/zeroth/module.modulemap", +// CHECK-NEXT: "command-line": [ +// CHECK: ], +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/first/module.modulemap", +// CHECK-NEXT: "[[PREFIX]]/second/module.modulemap", +// CHECK-NEXT: "[[PREFIX]]/second/second.modulemap", +// CHECK-NEXT: "[[PREFIX]]/zeroth/module.modulemap", +// CHECK-NEXT: "[[PREFIX]]/zeroth/zeroth.h" +// CHECK-NEXT: ], +// CHECK-NEXT: "name": "zeroth" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "translation-units": [ +// CHECK-NEXT: { +// CHECK-NEXT: "commands": [ +// CHECK-NEXT: { +// CHECK-NEXT: "clang-context-hash": "{{.*}}", +// CHECK-NEXT: "clang-module-deps": [ +// CHECK-NEXT: { +// CHECK-NEXT: "context-hash": "{{.*}}", +// CHECK-NEXT: "module-name": "zeroth" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "command-line": [ +// CHECK: ], +// CHECK-NEXT: "executable": "clang", +// CHECK-NEXT: "file-deps": [ +// CHECK-NEXT: "[[PREFIX]]/tu.m" +// CHECK-NEXT: ], +// CHECK-NEXT: "input-file": "[[PREFIX]]/tu.m" +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } + +// RUN: %deps-to-rsp --module-name=first %t/result.json > %t/first.cc1.rsp +// RUN: %deps-to-rsp --module-name=first_other %t/result.json > %t/first_other.cc1.rsp +// RUN: %deps-to-rsp --module-name=second %t/result.json > %t/second.cc1.rsp +// RUN: %deps-to-rsp --module-name=zeroth %t/result.json > %t/zeroth.cc1.rsp +// RUN: %clang @%t/first.cc1.rsp +// RUN: %clang @%t/first_other.cc1.rsp +// RUN: %clang @%t/second.cc1.rsp +// RUN: %clang @%t/zeroth.cc1.rsp Index: clang/lib/Serialization/ASTWriter.cpp =================================================================== --- clang/lib/Serialization/ASTWriter.cpp +++ clang/lib/Serialization/ASTWriter.cpp @@ -161,12 +161,14 @@ namespace { -std::set<const FileEntry *> GetAllModuleMaps(const HeaderSearch &HS, - Module *RootModule) { +std::set<const FileEntry *> GetAffectingModuleMaps(const Preprocessor &PP, + Module *RootModule) { std::set<const FileEntry *> ModuleMaps{}; std::set<const Module *> ProcessedModules; SmallVector<const Module *> ModulesToProcess{RootModule}; + const HeaderSearch &HS = PP.getHeaderSearchInfo(); + SmallVector<const FileEntry *, 16> FilesByUID; HS.getFileMgr().GetUniqueIDMapping(FilesByUID); @@ -191,12 +193,27 @@ } const ModuleMap &MM = HS.getModuleMap(); + SourceManager &SourceMgr = PP.getSourceManager(); + + auto ForIncludeChain = [&](FileEntryRef F, + llvm::function_ref<void(FileEntryRef)> CB) { + CB(F); + FileID FID = SourceMgr.translateFile(F); + SourceLocation Loc = SourceMgr.getIncludeLoc(FID); + while (Loc.isValid()) { + FID = SourceMgr.getFileID(Loc); + CB(*SourceMgr.getFileEntryRefForID(FID)); + Loc = SourceMgr.getIncludeLoc(FID); + } + }; auto ProcessModuleOnce = [&](const Module *M) { for (const Module *Mod = M; Mod; Mod = Mod->Parent) if (ProcessedModules.insert(Mod).second) if (auto ModuleMapFile = MM.getModuleMapFileForUniquing(Mod)) - ModuleMaps.insert(*ModuleMapFile); + ForIncludeChain(*ModuleMapFile, [&](FileEntryRef F) { + ModuleMaps.insert(F); + }); }; for (const Module *CurrentModule : ModulesToProcess) { @@ -1468,10 +1485,8 @@ Stream.EmitRecord(ORIGINAL_FILE_ID, Record); std::set<const FileEntry *> AffectingModuleMaps; - if (WritingModule) { - AffectingModuleMaps = - GetAllModuleMaps(PP.getHeaderSearchInfo(), WritingModule); - } + if (WritingModule) + AffectingModuleMaps = GetAffectingModuleMaps(PP, WritingModule); WriteInputFiles(Context.SourceMgr, PP.getHeaderSearchInfo().getHeaderSearchOpts(),
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits