Skip to content

Commit

Permalink
[clang][modules][deps] Including module maps are affecting
Browse files Browse the repository at this point in the history
With this patch, we mark module maps that include an affecting `extern` module map as also affecting. This is a generalization of D137197: now we don't require the importing module map to describe parent of the extern module.

Depends on D137198.

Reviewed By: Bigcheese

Differential Revision: https://reviews.llvm.org/D137206
  • Loading branch information
jansvoboda11 committed Dec 2, 2022
1 parent f99e5a9 commit 83973cf
Show file tree
Hide file tree
Showing 2 changed files with 155 additions and 4 deletions.
24 changes: 20 additions & 4 deletions clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,14 @@ static TypeCode getTypeCodeForTypeClass(Type::TypeClass id) {

namespace {

std::set<const FileEntry *> GetAffectingModuleMaps(const HeaderSearch &HS,
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);

Expand All @@ -191,12 +193,27 @@ std::set<const FileEntry *> GetAffectingModuleMaps(const HeaderSearch &HS,
}

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) {
Expand Down Expand Up @@ -4545,8 +4562,7 @@ void ASTWriter::collectNonAffectingInputFiles() {
if (!WritingModule)
return;

auto AffectingModuleMaps =
GetAffectingModuleMaps(PP->getHeaderSearchInfo(), WritingModule);
auto AffectingModuleMaps = GetAffectingModuleMaps(*PP, WritingModule);

unsigned FileIDAdjustment = 0;
unsigned OffsetAdjustment = 0;
Expand Down
135 changes: 135 additions & 0 deletions clang/test/ClangScanDeps/modules-extern-unrelated.m
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 83973cf

Please sign in to comment.