diff --git a/clang/include/clang/Lex/ModuleMap.h b/clang/include/clang/Lex/ModuleMap.h --- a/clang/include/clang/Lex/ModuleMap.h +++ b/clang/include/clang/Lex/ModuleMap.h @@ -581,6 +581,12 @@ return ModuleScopeIDs[ExistingModule] < CurrentModuleScopeID; } + /// Check whether a framework module can be inferred in the given directory. + bool canInferFrameworkModule(const DirectoryEntry *Dir) const { + auto It = InferredDirectories.find(Dir); + return It != InferredDirectories.end() && It->getSecond().InferModules; + } + /// Retrieve the module map file containing the definition of the given /// module. /// diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -465,6 +465,15 @@ if (SrcMgr.getBufferOrFake(ModuleMapID).getBufferSize() == Offset) Offset = 0; + // Infer framework module if possible. + if (HS.getModuleMap().canInferFrameworkModule(ModuleMap->getDir())) { + SmallString<128> InferredFrameworkPath = ModuleMap->getDir()->getName(); + llvm::sys::path::append(InferredFrameworkPath, + CI.getLangOpts().ModuleName + ".framework"); + if (auto Dir = CI.getFileManager().getDirectory(InferredFrameworkPath)) + (void)HS.getModuleMap().inferFrameworkModule(*Dir, IsSystem, nullptr); + } + return false; } diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -46,6 +46,7 @@ CI.getFrontendOpts().IsSystemModule = Deps.IsSystem; CI.getLangOpts()->ImplicitModules = false; + CI.getHeaderSearchOpts().ImplicitModuleMaps = false; // Report the prebuilt modules this module uses. for (const auto &PrebuiltModule : Deps.PrebuiltModuleDeps) { diff --git a/clang/test/ClangScanDeps/modules-full.cpp b/clang/test/ClangScanDeps/modules-full.cpp --- a/clang/test/ClangScanDeps/modules-full.cpp +++ b/clang/test/ClangScanDeps/modules-full.cpp @@ -53,6 +53,7 @@ // CHECK-NO-ABS-NOT: "-fmodule-file={{.*}}" // CHECK-ABS: "-fmodule-file=[[PREFIX]]/module-cache{{(_clangcl)?}}/[[HASH_H2_DINCLUDE]]/header2-{{[A-Z0-9]+}}.pcm" // CHECK-CUSTOM: "-fmodule-file=[[PREFIX]]/custom/[[HASH_H2_DINCLUDE]]/header2-{{[A-Z0-9]+}}.pcm" +// CHECK-NOT: "-fimplicit-module-maps" // CHECK: "-fmodule-name=header1" // CHECK: "-fno-implicit-modules" // CHECK: ], @@ -69,6 +70,7 @@ // CHECK-NEXT: "command-line": [ // CHECK-NEXT: "-cc1", // CHECK: "-emit-module", +// CHECK-NOT: "-fimplicit-module-maps", // CHECK: "-fmodule-name=header1", // CHECK: "-fno-implicit-modules", // CHECK: ], @@ -86,6 +88,7 @@ // CHECK-NEXT: "-cc1", // CHECK: "-emit-module", // CHECK: "-fmodule-name=header2", +// CHECK-NOT: "-fimplicit-module-maps", // CHECK: "-fno-implicit-modules", // CHECK: ], // CHECK-NEXT: "context-hash": "[[HASH_H2_DINCLUDE]]", diff --git a/clang/test/ClangScanDeps/modules-inferred.m b/clang/test/ClangScanDeps/modules-inferred.m --- a/clang/test/ClangScanDeps/modules-inferred.m +++ b/clang/test/ClangScanDeps/modules-inferred.m @@ -25,6 +25,7 @@ // CHECK-NEXT: "command-line": [ // CHECK-NEXT: "-cc1", // CHECK: "-emit-module", +// CHECK-NOT: "-fimplicit-module-maps", // CHECK: "-fmodule-name=Inferred", // CHECK: "-fno-implicit-modules", // CHECK: ], diff --git a/clang/test/ClangScanDeps/modules-pch.c b/clang/test/ClangScanDeps/modules-pch.c --- a/clang/test/ClangScanDeps/modules-pch.c +++ b/clang/test/ClangScanDeps/modules-pch.c @@ -22,6 +22,7 @@ // CHECK-PCH-NEXT: "-cc1" // CHECK-PCH: "-emit-module" // CHECK-PCH: "-fmodules" +// CHECK-PCH-NOT: "-fimplicit-module-maps" // CHECK-PCH: "-fmodule-name=ModCommon1" // CHECK-PCH: "-fno-implicit-modules" // CHECK-PCH: ], @@ -39,6 +40,7 @@ // CHECK-PCH-NEXT: "-cc1" // CHECK-PCH: "-emit-module" // CHECK-PCH: "-fmodules" +// CHECK-PCH-NOT: "-fimplicit-module-maps" // CHECK-PCH: "-fmodule-name=ModCommon2" // CHECK-PCH: "-fno-implicit-modules" // CHECK-PCH: ], @@ -63,6 +65,7 @@ // CHECK-PCH: "-emit-module" // CHECK-PCH: "-fmodule-file=[[PREFIX]]/build/[[HASH_MOD_COMMON_2]]/ModCommon2-{{.*}}.pcm" // CHECK-PCH: "-fmodules" +// CHECK-PCH-NOT: "-fimplicit-module-maps" // CHECK-PCH: "-fmodule-name=ModPCH" // CHECK-PCH: "-fno-implicit-modules" // CHECK-PCH: ], @@ -140,6 +143,7 @@ // CHECK-TU-NEXT: "command-line": [ // CHECK-TU-NEXT: "-cc1", // CHECK-TU: "-emit-module", +// CHECK-TU-NOT: "-fimplicit-module-maps", // CHECK-TU: "-fmodule-name=ModTU", // CHECK-TU: "-fno-implicit-modules", // CHECK-TU: ], @@ -206,6 +210,7 @@ // CHECK-TU-WITH-COMMON: "-fmodule-map-file=[[PREFIX]]/module.modulemap" // CHECK-TU-WITH-COMMON: "-emit-module", // CHECK-TU-WITH-COMMON: "-fmodule-file=[[PREFIX]]/build/{{.*}}/ModCommon1-{{.*}}.pcm", +// CHECK-TU-WITH-COMMON-NOT: "-fimplicit-module-maps", // CHECK-TU-WITH-COMMON: "-fmodule-name=ModTUWithCommon", // CHECK-TU-WITH-COMMON: "-fno-implicit-modules", // CHECK-TU-WITH-COMMON: ], diff --git a/clang/test/Modules/explicit-build-inferred.cpp b/clang/test/Modules/explicit-build-inferred.cpp --- a/clang/test/Modules/explicit-build-inferred.cpp +++ b/clang/test/Modules/explicit-build-inferred.cpp @@ -1,11 +1,10 @@ // RUN: rm -rf %t && mkdir %t // -// RUN: %clang_cc1 -fmodules -fno-implicit-modules -fimplicit-module-maps \ +// RUN: %clang_cc1 -fmodules -fno-implicit-modules \ // RUN: -emit-module -x c++ %S/Inputs/explicit-build-inferred/frameworks/module.modulemap \ // RUN: -fmodule-name=Inferred -o %t/Inferred.pcm -F %S/Inputs/explicit-build-inferred/frameworks // // RUN: %clang_cc1 -fmodules -fno-implicit-modules -fsyntax-only %s \ -// RUN: -fmodule-map-file=%S/Inputs/explicit-build-inferred/frameworks/module.modulemap \ // RUN: -fmodule-file=%t/Inferred.pcm -F %S/Inputs/explicit-build-inferred/frameworks #include