Author: Michael Spencer
Date: 2026-04-07T16:03:20-07:00
New Revision: 8c389f3eb2e713c2195a4d3dd4b6894fab783a10

URL: 
https://github.com/llvm/llvm-project/commit/8c389f3eb2e713c2195a4d3dd4b6894fab783a10
DIFF: 
https://github.com/llvm/llvm-project/commit/8c389f3eb2e713c2195a4d3dd4b6894fab783a10.diff

LOG: [clang] Report direct module deps for explicitly built modules (#190757)

Implicitly built modules do not include PCM paths in .d files because
the compiler is the one managing them, but for explicitly built
modules the build system needs to know about them so that if one is
deleted the build system will rebuild it.

Explicitly built modules should only report direct dependencies, as
the build system knows about each PCM in the module graph. This adds
`-fmodule-file-deps=direct` to support that, and changes dependency
scanning to use this in the explicit build commands it outputs.

Assisted-by: claude-opus-4.6

Added: 
    clang/test/Driver/module-file-direct-deps.c
    clang/test/Modules/dependency-gen-direct-module-deps.m

Modified: 
    clang/include/clang/Frontend/DependencyOutputOptions.h
    clang/include/clang/Frontend/Utils.h
    clang/include/clang/Options/Options.td
    clang/include/clang/Serialization/ASTReader.h
    clang/lib/DependencyScanning/DependencyScannerImpl.cpp
    clang/lib/DependencyScanning/ModuleDepCollector.cpp
    clang/lib/Driver/ToolChains/Clang.cpp
    clang/lib/Frontend/DependencyFile.cpp
    clang/lib/Frontend/Rewrite/FrontendActions.cpp
    clang/lib/Serialization/ASTReader.cpp
    clang/test/ClangScanDeps/generate-modules-path-args.c
    clang/test/Driver/pch-deps.c
    clang/test/Modules/dependency-gen-pch.m

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Frontend/DependencyOutputOptions.h 
b/clang/include/clang/Frontend/DependencyOutputOptions.h
index d92a87d78d7c5..98728f4d53b43 100644
--- a/clang/include/clang/Frontend/DependencyOutputOptions.h
+++ b/clang/include/clang/Frontend/DependencyOutputOptions.h
@@ -29,6 +29,13 @@ enum ExtraDepKind {
   EDK_DepFileEntry,
 };
 
+/// ModuleFileDepsKind - Whether to include module file dependencies.
+enum ModuleFileDepsKind {
+  MFDK_None,   ///< Do not include module file dependencies.
+  MFDK_All,    ///< Include all module file dependencies.
+  MFDK_Direct, ///< Include only directly imported module file dependencies.
+};
+
 /// DependencyOutputOptions - Options for controlling the compiler dependency
 /// file generation.
 class DependencyOutputOptions {
@@ -43,8 +50,8 @@ class DependencyOutputOptions {
                                      /// problems.
   LLVM_PREFERRED_TYPE(bool)
   unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency 
list
-  LLVM_PREFERRED_TYPE(bool)
-  unsigned IncludeModuleFiles : 1; ///< Include module file dependencies.
+  LLVM_PREFERRED_TYPE(ModuleFileDepsKind)
+  unsigned IncludeModuleFiles : 2; ///< Include module file dependencies.
   LLVM_PREFERRED_TYPE(bool)
   unsigned ShowSkippedHeaderIncludes : 1; ///< With ShowHeaderIncludes, show
                                           /// also includes that were skipped
@@ -89,7 +96,7 @@ class DependencyOutputOptions {
 public:
   DependencyOutputOptions()
       : IncludeSystemHeaders(0), ShowHeaderIncludes(0), UsePhonyTargets(0),
-        AddMissingHeaderDeps(0), IncludeModuleFiles(0),
+        AddMissingHeaderDeps(0), IncludeModuleFiles(MFDK_None),
         ShowSkippedHeaderIncludes(0), HeaderIncludeFormat(HIFMT_Textual),
         HeaderIncludeFiltering(HIFIL_None) {}
 };

diff  --git a/clang/include/clang/Frontend/Utils.h 
b/clang/include/clang/Frontend/Utils.h
index 1c561b47b5c47..71a009496a1f0 100644
--- a/clang/include/clang/Frontend/Utils.h
+++ b/clang/include/clang/Frontend/Utils.h
@@ -72,8 +72,9 @@ class DependencyCollector {
   /// to the list of dependencies.
   ///
   /// The default implementation ignores <built-in> and system files.
-  virtual bool sawDependency(StringRef Filename, bool FromModule,
-                             bool IsSystem, bool IsModuleFile, bool IsMissing);
+  virtual bool sawDependency(StringRef Filename, bool FromModule, bool 
IsSystem,
+                             bool IsModuleFile, bool IsDirectModuleImport,
+                             bool IsMissing);
 
   /// Called when the end of the main file is reached.
   virtual void finishedMainFile(DiagnosticsEngine &Diags) {}
@@ -85,7 +86,7 @@ class DependencyCollector {
   /// sawDependency() returns true.
   virtual void maybeAddDependency(StringRef Filename, bool FromModule,
                                   bool IsSystem, bool IsModuleFile,
-                                  bool IsMissing);
+                                  bool IsDirectModuleImport, bool IsMissing);
 
 protected:
   /// Return true if the filename was added to the list of dependencies, false
@@ -112,7 +113,8 @@ class DependencyFileGenerator : public DependencyCollector {
   bool needSystemDependencies() final { return IncludeSystemHeaders; }
 
   bool sawDependency(StringRef Filename, bool FromModule, bool IsSystem,
-                     bool IsModuleFile, bool IsMissing) final;
+                     bool IsModuleFile, bool IsDirectModuleImport,
+                     bool IsMissing) final;
 
 protected:
   void outputDependencyFile(llvm::raw_ostream &OS);
@@ -126,7 +128,7 @@ class DependencyFileGenerator : public DependencyCollector {
   bool PhonyTarget;
   bool AddMissingHeaderDeps;
   bool SeenMissingHeader;
-  bool IncludeModuleFiles;
+  ModuleFileDepsKind IncludeModuleFiles;
   DependencyOutputFormat OutputFormat;
   unsigned InputFileIndex;
 };

diff  --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index 5e4ffd177e870..bffb3dfb27485 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -3857,6 +3857,9 @@ def fno_module_maps : Flag <["-"], "fno-module-maps">, 
Alias<fno_implicit_module
 def fno_modules_strict_decluse : Flag <["-"], "fno-strict-modules-decluse">, 
Group<f_Group>;
 def fmodule_file_deps : Flag <["-"], "fmodule-file-deps">, Group<f_Group>;
 def fno_module_file_deps : Flag <["-"], "fno-module-file-deps">, 
Group<f_Group>;
+def fmodule_file_deps_EQ : Joined<["-"], "fmodule-file-deps=">, Group<f_Group>,
+  HelpText<"Include module files in dependency output">,
+  Values<"none,all,direct">;
 def fno_ms_extensions : Flag<["-"], "fno-ms-extensions">, Group<f_Group>,
   Visibility<[ClangOption, CLOption]>;
 def fno_ms_compatibility : Flag<["-"], "fno-ms-compatibility">, Group<f_Group>,
@@ -8504,9 +8507,11 @@ let Visibility = [CC1Option] in {
 def sys_header_deps : Flag<["-"], "sys-header-deps">,
   HelpText<"Include system headers in dependency output">,
   MarshallingInfoFlag<DependencyOutputOpts<"IncludeSystemHeaders">>;
-def module_file_deps : Flag<["-"], "module-file-deps">,
+def module_file_deps_EQ : Joined<["-"], "module-file-deps=">,
   HelpText<"Include module files in dependency output">,
-  MarshallingInfoFlag<DependencyOutputOpts<"IncludeModuleFiles">>;
+  Values<"none,all,direct">,
+  NormalizedValues<["MFDK_None", "MFDK_All", "MFDK_Direct"]>,
+  MarshallingInfoEnum<DependencyOutputOpts<"IncludeModuleFiles">, "MFDK_None">;
 def header_include_file : Separate<["-"], "header-include-file">,
   HelpText<"Filename (or -) to write header include output to">,
   MarshallingInfoString<DependencyOutputOpts<"HeaderIncludeOutputFile">>;

diff  --git a/clang/include/clang/Serialization/ASTReader.h 
b/clang/include/clang/Serialization/ASTReader.h
index e66fd3d1eccb7..8394647885bd3 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -224,7 +224,8 @@ class ASTReaderListener {
 
   /// This is called for each AST file loaded.
   virtual void visitModuleFile(ModuleFileName Filename,
-                               serialization::ModuleKind Kind) {}
+                               serialization::ModuleKind Kind,
+                               bool DirectlyImported) {}
 
   /// Returns true if this \c ASTReaderListener wants to receive the
   /// input files of the AST file via \c visitInputFile, false otherwise.
@@ -313,8 +314,8 @@ class ChainedASTReaderListener : public ASTReaderListener {
   void ReadCounter(const serialization::ModuleFile &M, uint32_t Value) 
override;
   bool needsInputFileVisitation() override;
   bool needsSystemInputFileVisitation() override;
-  void visitModuleFile(ModuleFileName Filename,
-                       serialization::ModuleKind Kind) override;
+  void visitModuleFile(ModuleFileName Filename, serialization::ModuleKind Kind,
+                       bool DirectlyImported) override;
   bool visitInputFile(StringRef Filename, bool isSystem,
                       bool isOverridden, bool isExplicitModule) override;
   void readModuleFileExtension(

diff  --git a/clang/lib/DependencyScanning/DependencyScannerImpl.cpp 
b/clang/lib/DependencyScanning/DependencyScannerImpl.cpp
index 1940d2f275c73..c752f76e53712 100644
--- a/clang/lib/DependencyScanning/DependencyScannerImpl.cpp
+++ b/clang/lib/DependencyScanning/DependencyScannerImpl.cpp
@@ -135,8 +135,8 @@ class PrebuiltModuleListener : public ASTReaderListener {
   }
 
   /// Update which module that is being actively traversed.
-  void visitModuleFile(ModuleFileName Filename,
-                       serialization::ModuleKind Kind) override {
+  void visitModuleFile(ModuleFileName Filename, serialization::ModuleKind Kind,
+                       bool DirectlyImported) override {
     // If the CurrentFile is not
     // considered stable, update any of it's transitive dependents.
     auto PrebuiltEntryIt = PrebuiltModulesASTMap.find(CurrentFile);
@@ -207,7 +207,8 @@ static bool visitPrebuiltModule(StringRef 
PrebuiltModuleFilename,
                                   Diags, StableDirs);
 
   
Listener.visitModuleFile(ModuleFileName::makeExplicit(PrebuiltModuleFilename),
-                           serialization::MK_ExplicitModule);
+                           serialization::MK_ExplicitModule,
+                           /*DirectlyImported=*/true);
   if (ASTReader::readASTFileControlBlock(
           PrebuiltModuleFilename, CI.getFileManager(), CI.getModuleCache(),
           CI.getPCHContainerReader(),
@@ -222,7 +223,8 @@ static bool visitPrebuiltModule(StringRef 
PrebuiltModuleFilename,
     // change the values of HeaderSearchOptions::PrebuiltModuleFiles from plain
     // paths to ModuleFileName.
     Listener.visitModuleFile(ModuleFileName::makeExplicit(Worklist.back()),
-                             serialization::MK_ExplicitModule);
+                             serialization::MK_ExplicitModule,
+                             /*DirectlyImported=*/false);
     if (ASTReader::readASTFileControlBlock(
             Worklist.pop_back_val(), CI.getFileManager(), CI.getModuleCache(),
             CI.getPCHContainerReader(),

diff  --git a/clang/lib/DependencyScanning/ModuleDepCollector.cpp 
b/clang/lib/DependencyScanning/ModuleDepCollector.cpp
index 35c9ee64c262f..06347fb5ade72 100644
--- a/clang/lib/DependencyScanning/ModuleDepCollector.cpp
+++ b/clang/lib/DependencyScanning/ModuleDepCollector.cpp
@@ -279,6 +279,7 @@ makeCommonInvocationForModuleBuild(CompilerInvocation CI) {
   if (!CI.getDependencyOutputOpts().OutputFile.empty())
     CI.getDependencyOutputOpts().OutputFile = "-";
   CI.getDependencyOutputOpts().Targets.clear();
+  CI.getDependencyOutputOpts().IncludeModuleFiles = MFDK_Direct;
 
   CI.getFrontendOpts().ProgramAction = frontend::GenerateModule;
   CI.getLangOpts().ModuleName.clear();
@@ -440,6 +441,7 @@ void 
ModuleDepCollector::applyDiscoveredDependencies(CompilerInvocation &CI) {
   CI.clearImplicitModuleBuildOptions();
   resetBenignCodeGenOptions(CI.getFrontendOpts().ProgramAction,
                             CI.getLangOpts(), CI.getCodeGenOpts());
+  CI.getDependencyOutputOpts().IncludeModuleFiles = MFDK_Direct;
 
   if (llvm::any_of(CI.getFrontendOpts().Inputs, needsModules)) {
     Preprocessor &PP = ScanInstance.getPreprocessor();

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 5d259d162fa1f..0d5722cd536f2 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -914,10 +914,24 @@ void Clang::AddPreprocessingOptions(Compilation &C, const 
JobAction &JA,
     if (ArgM->getOption().matches(options::OPT_M) ||
         ArgM->getOption().matches(options::OPT_MD))
       CmdArgs.push_back("-sys-header-deps");
-    if ((isa<PrecompileJobAction>(JA) &&
-         !Args.hasArg(options::OPT_fno_module_file_deps)) ||
-        Args.hasArg(options::OPT_fmodule_file_deps))
-      CmdArgs.push_back("-module-file-deps");
+
+    // Determine module file deps mode.
+    StringRef ModuleFileDepsVal;
+    if (Arg *A = Args.getLastArg(options::OPT_fmodule_file_deps_EQ,
+                                 options::OPT_fmodule_file_deps,
+                                 options::OPT_fno_module_file_deps)) {
+      if (A->getOption().matches(options::OPT_fmodule_file_deps_EQ))
+        ModuleFileDepsVal = A->getValue();
+      else if (A->getOption().matches(options::OPT_fmodule_file_deps))
+        ModuleFileDepsVal = "all";
+      else
+        ModuleFileDepsVal = "none";
+    } else if (isa<PrecompileJobAction>(JA)) {
+      ModuleFileDepsVal = "all";
+    }
+    if (!ModuleFileDepsVal.empty() && ModuleFileDepsVal != "none")
+      CmdArgs.push_back(
+          Args.MakeArgString("-module-file-deps=" + ModuleFileDepsVal));
   }
 
   if (Args.hasArg(options::OPT_MG)) {

diff  --git a/clang/lib/Frontend/DependencyFile.cpp 
b/clang/lib/Frontend/DependencyFile.cpp
index 64629abcaeb52..d56e17f14e9bc 100644
--- a/clang/lib/Frontend/DependencyFile.cpp
+++ b/clang/lib/Frontend/DependencyFile.cpp
@@ -49,7 +49,7 @@ struct DepCollectorPPCallbacks : public PPCallbacks {
       DepCollector.maybeAddDependency(
           llvm::sys::path::remove_leading_dotslash(*Filename),
           /*FromModule*/ false, isSystem(FileType), /*IsModuleFile*/ false,
-          /*IsMissing*/ false);
+          /*IsDirectModuleImport*/ false, /*IsMissing*/ false);
   }
 
   void FileSkipped(const FileEntryRef &SkippedFile, const Token &FilenameTok,
@@ -59,6 +59,7 @@ struct DepCollectorPPCallbacks : public PPCallbacks {
     DepCollector.maybeAddDependency(Filename, /*FromModule=*/false,
                                     /*IsSystem=*/isSystem(FileType),
                                     /*IsModuleFile=*/false,
+                                    /*IsDirectModuleImport=*/false,
                                     /*IsMissing=*/false);
   }
 
@@ -72,6 +73,7 @@ struct DepCollectorPPCallbacks : public PPCallbacks {
                                     /*FromModule*/ false,
                                     /*IsSystem*/ false,
                                     /*IsModuleFile*/ false,
+                                    /*IsDirectModuleImport*/ false,
                                     /*IsMissing*/ false);
   }
 
@@ -81,6 +83,7 @@ struct DepCollectorPPCallbacks : public PPCallbacks {
         /*FromModule=*/false,
         /*IsSystem=*/false,
         /*IsModuleFile=*/false,
+        /*IsDirectModuleImport=*/false,
         /*IsMissing=*/true);
     // Return true to silence the file not found diagnostic.
     return true;
@@ -97,6 +100,7 @@ struct DepCollectorPPCallbacks : public PPCallbacks {
       DepCollector.maybeAddDependency(FileName, /*FromModule*/ false,
                                       /*IsSystem*/ false,
                                       /*IsModuleFile*/ false,
+                                      /*IsDirectModuleImport*/ false,
                                       /*IsMissing*/ true);
     // Files that actually exist are handled by FileChanged.
   }
@@ -110,6 +114,7 @@ struct DepCollectorPPCallbacks : public PPCallbacks {
     DepCollector.maybeAddDependency(Filename,
                                     /*FromModule=*/false, false,
                                     /*IsModuleFile=*/false,
+                                    /*IsDirectModuleImport=*/false,
                                     /*IsMissing=*/false);
   }
 
@@ -123,6 +128,7 @@ struct DepCollectorPPCallbacks : public PPCallbacks {
     DepCollector.maybeAddDependency(Filename, /*FromModule=*/false,
                                     /*IsSystem=*/isSystem(FileType),
                                     /*IsModuleFile=*/false,
+                                    /*IsDirectModuleImport=*/false,
                                     /*IsMissing=*/false);
   }
 
@@ -141,6 +147,7 @@ struct DepCollectorMMCallbacks : public ModuleMapCallbacks {
     DepCollector.maybeAddDependency(Filename, /*FromModule*/ false,
                                     /*IsSystem*/ IsSystem,
                                     /*IsModuleFile*/ false,
+                                    /*IsDirectModuleImport*/ false,
                                     /*IsMissing*/ false);
   }
 };
@@ -154,10 +161,11 @@ struct DepCollectorASTListener : public ASTReaderListener 
{
   bool needsSystemInputFileVisitation() override {
     return DepCollector.needSystemDependencies();
   }
-  void visitModuleFile(ModuleFileName Filename,
-                       serialization::ModuleKind Kind) override {
+  void visitModuleFile(ModuleFileName Filename, serialization::ModuleKind Kind,
+                       bool DirectlyImported) override {
     DepCollector.maybeAddDependency(Filename, /*FromModule*/ true,
                                     /*IsSystem*/ false, /*IsModuleFile*/ true,
+                                    /*IsDirectModuleImport*/ DirectlyImported,
                                     /*IsMissing*/ false);
   }
   bool visitInputFile(StringRef Filename, bool IsSystem,
@@ -172,6 +180,7 @@ struct DepCollectorASTListener : public ASTReaderListener {
 
     DepCollector.maybeAddDependency(Filename, /*FromModule*/ true, IsSystem,
                                     /*IsModuleFile*/ false,
+                                    /*IsDirectModuleImport*/ false,
                                     /*IsMissing*/ false);
     return true;
   }
@@ -181,8 +190,10 @@ struct DepCollectorASTListener : public ASTReaderListener {
 void DependencyCollector::maybeAddDependency(StringRef Filename,
                                              bool FromModule, bool IsSystem,
                                              bool IsModuleFile,
+                                             bool IsDirectModuleImport,
                                              bool IsMissing) {
-  if (sawDependency(Filename, FromModule, IsSystem, IsModuleFile, IsMissing))
+  if (sawDependency(Filename, FromModule, IsSystem, IsModuleFile,
+                    IsDirectModuleImport, IsMissing))
     addDependency(Filename);
 }
 
@@ -211,6 +222,7 @@ static bool isSpecialFilename(StringRef Filename) {
 
 bool DependencyCollector::sawDependency(StringRef Filename, bool FromModule,
                                         bool IsSystem, bool IsModuleFile,
+                                        bool IsDirectModuleImport,
                                         bool IsMissing) {
   return !isSpecialFilename(Filename) &&
          (needSystemDependencies() || !IsSystem);
@@ -233,7 +245,8 @@ DependencyFileGenerator::DependencyFileGenerator(
       IncludeSystemHeaders(Opts.IncludeSystemHeaders),
       PhonyTarget(Opts.UsePhonyTargets),
       AddMissingHeaderDeps(Opts.AddMissingHeaderDeps), 
SeenMissingHeader(false),
-      IncludeModuleFiles(Opts.IncludeModuleFiles),
+      IncludeModuleFiles(
+          static_cast<ModuleFileDepsKind>(Opts.IncludeModuleFiles)),
       OutputFormat(Opts.OutputFormat), InputFileIndex(0) {
   for (const auto &ExtraDep : Opts.ExtraDeps) {
     if (addDependency(ExtraDep.first))
@@ -251,6 +264,7 @@ void 
DependencyFileGenerator::attachToPreprocessor(Preprocessor &PP) {
 
 bool DependencyFileGenerator::sawDependency(StringRef Filename, bool 
FromModule,
                                             bool IsSystem, bool IsModuleFile,
+                                            bool IsDirectModuleImport,
                                             bool IsMissing) {
   if (IsMissing) {
     // Handle the case of missing file from an inclusion directive.
@@ -259,8 +273,12 @@ bool DependencyFileGenerator::sawDependency(StringRef 
Filename, bool FromModule,
     SeenMissingHeader = true;
     return false;
   }
-  if (IsModuleFile && !IncludeModuleFiles)
-    return false;
+  if (IsModuleFile) {
+    if (IncludeModuleFiles == MFDK_None)
+      return false;
+    if (IncludeModuleFiles == MFDK_Direct && !IsDirectModuleImport)
+      return false;
+  }
 
   if (isSpecialFilename(Filename))
     return false;

diff  --git a/clang/lib/Frontend/Rewrite/FrontendActions.cpp 
b/clang/lib/Frontend/Rewrite/FrontendActions.cpp
index 1e12d3a6ea3df..61efb3f3446f2 100644
--- a/clang/lib/Frontend/Rewrite/FrontendActions.cpp
+++ b/clang/lib/Frontend/Rewrite/FrontendActions.cpp
@@ -211,8 +211,8 @@ class RewriteIncludesAction::RewriteImportsListener : 
public ASTReaderListener {
   RewriteImportsListener(CompilerInstance &CI, std::shared_ptr<raw_ostream> 
Out)
       : CI(CI), Out(Out) {}
 
-  void visitModuleFile(ModuleFileName Filename,
-                       serialization::ModuleKind Kind) override {
+  void visitModuleFile(ModuleFileName Filename, serialization::ModuleKind Kind,
+                       bool DirectlyImported) override {
     serialization::ModuleFile *MF =
         CI.getASTReader()->getModuleManager().lookupByFileName(Filename);
     assert(MF && "missing module file for loaded module?");

diff  --git a/clang/lib/Serialization/ASTReader.cpp 
b/clang/lib/Serialization/ASTReader.cpp
index b211b0d32e1de..2ad6de58f56e1 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -242,9 +242,10 @@ bool 
ChainedASTReaderListener::needsSystemInputFileVisitation() {
 }
 
 void ChainedASTReaderListener::visitModuleFile(ModuleFileName Filename,
-                                               ModuleKind Kind) {
-  First->visitModuleFile(Filename, Kind);
-  Second->visitModuleFile(Filename, Kind);
+                                               ModuleKind Kind,
+                                               bool DirectlyImported) {
+  First->visitModuleFile(Filename, Kind, DirectlyImported);
+  Second->visitModuleFile(Filename, Kind, DirectlyImported);
 }
 
 bool ChainedASTReaderListener::visitInputFile(StringRef Filename,
@@ -3308,7 +3309,7 @@ ASTReader::ReadControlBlock(ModuleFile &F,
       }
 
       if (Listener)
-        Listener->visitModuleFile(F.FileName, F.Kind);
+        Listener->visitModuleFile(F.FileName, F.Kind, F.isDirectlyImported());
 
       if (Listener && Listener->needsInputFileVisitation()) {
         unsigned N = Listener->needsSystemInputFileVisitation() ? NumInputs

diff  --git a/clang/test/ClangScanDeps/generate-modules-path-args.c 
b/clang/test/ClangScanDeps/generate-modules-path-args.c
index a303b5883bd3d..d304df74ea825 100644
--- a/clang/test/ClangScanDeps/generate-modules-path-args.c
+++ b/clang/test/ClangScanDeps/generate-modules-path-args.c
@@ -26,6 +26,7 @@
 // CHECK-NEXT:         "[[PREFIX]]{{.*}}Mod{{.*}}.pcm"
 // CHECK:              "-dependency-file"
 // CHECK-NEXT:         "[[PREFIX]]{{.*}}Mod{{.*}}.d"
+// CHECK:              "-module-file-deps=direct"
 // CHECK:            ],
 
 // DEPS_MT1:      "-MT"
@@ -46,6 +47,12 @@
 // WITHOUT-NOT:          "-MT"
 // WITHOUT:            ],
 
+// Check that -module-file-deps=direct is present in the TU command.
+// CHECK:      "translation-units":
+// CHECK:          "command-line": [
+// CHECK:            "-module-file-deps=direct"
+// CHECK:          ]
+
 //--- cdb.json.template
 [{
   "directory": "DIR",

diff  --git a/clang/test/Driver/module-file-direct-deps.c 
b/clang/test/Driver/module-file-direct-deps.c
new file mode 100644
index 0000000000000..cc9fe973dac70
--- /dev/null
+++ b/clang/test/Driver/module-file-direct-deps.c
@@ -0,0 +1,28 @@
+// Test -fmodule-file-deps= with explicit values.
+// RUN: %clang -c %s -o %t.o -MMD -MT dependencies -MF %t.d 
-fmodule-file-deps=direct -### 2> %t
+// RUN: FileCheck %s -input-file=%t
+// CHECK: -dependency-file
+// CHECK: "-module-file-deps=direct"
+
+// RUN: %clang -c %s -o %t.o -MMD -MT dependencies -MF %t.d 
-fmodule-file-deps=all -### 2> %t
+// RUN: FileCheck %s -check-prefix=CHECK-ALL -input-file=%t
+// CHECK-ALL: -dependency-file
+// CHECK-ALL: "-module-file-deps=all"
+
+// RUN: %clang -c %s -o %t.o -MMD -MT dependencies -MF %t.d 
-fmodule-file-deps=none -### 2> %t
+// RUN: FileCheck %s -check-prefix=CHECK-NONE -input-file=%t
+// CHECK-NONE: -dependency-file
+// CHECK-NONE-NOT: -module-file-deps=
+
+// Test legacy -fmodule-file-deps maps to =all.
+// RUN: %clang -c %s -o %t.o -MMD -MT dependencies -MF %t.d -fmodule-file-deps 
-### 2> %t
+// RUN: FileCheck %s -check-prefix=CHECK-LEGACY -input-file=%t
+// CHECK-LEGACY: -dependency-file
+// CHECK-LEGACY: "-module-file-deps=all"
+
+// Test legacy -fno-module-file-deps suppresses module deps.
+// RUN: %clang -c %s -o %t.o -MMD -MT dependencies -MF %t.d \
+// RUN:     -fmodule-file-deps -fno-module-file-deps -### 2> %t
+// RUN: FileCheck %s -check-prefix=CHECK-LEGACY-NEG -input-file=%t
+// CHECK-LEGACY-NEG: -dependency-file
+// CHECK-LEGACY-NEG-NOT: -module-file-deps=

diff  --git a/clang/test/Driver/pch-deps.c b/clang/test/Driver/pch-deps.c
index 2c140e50144ea..4af4ced98e30c 100644
--- a/clang/test/Driver/pch-deps.c
+++ b/clang/test/Driver/pch-deps.c
@@ -1,21 +1,25 @@
+// PCH implies -module-file-deps=all by default.
 // RUN: %clang -x c-header %s -o %t.pch -MMD -MT dependencies -MF %t.d -### 2> 
%t
 // RUN: FileCheck %s -input-file=%t
 // CHECK: -emit-pch
 // CHECK: -dependency-file
-// CHECK: -module-file-deps
+// CHECK: "-module-file-deps=all"
 
+// Non-PCH does not get module-file-deps.
 // RUN: %clang -c %s -o %t -MMD -MT dependencies -MF %t.d -### 2> %t
 // RUN: FileCheck %s -check-prefix=CHECK-NOPCH -input-file=%t
 // CHECK-NOPCH: -dependency-file
-// CHECK-NOPCH-NOT: -module-file-deps
+// CHECK-NOPCH-NOT: -module-file-deps=
 
+// -fno-module-file-deps overrides PCH default.
 // RUN: %clang -x c-header %s -o %t.pch -MMD -MT dependencies -MF %t.d \
 // RUN:     -fno-module-file-deps -### 2> %t
 // RUN: FileCheck %s -check-prefix=CHECK-EXPLICIT -input-file=%t
 // CHECK-EXPLICIT: -dependency-file
-// CHECK-EXPLICIT-NOT: -module-file-deps
+// CHECK-EXPLICIT-NOT: -module-file-deps=
 
+// Explicit -fmodule-file-deps on non-PCH.
 // RUN: %clang -x c++ %s -o %t.o -MMD -MT dependencies -MF %t.d 
-fmodule-file-deps -### 2> %t
 // RUN: FileCheck %s -check-prefix=CHECK-EXPLICIT-NOPCH -input-file=%t
 // CHECK-EXPLICIT-NOPCH: -dependency-file
-// CHECK-EXPLICIT-NOPCH: -module-file-deps
+// CHECK-EXPLICIT-NOPCH: "-module-file-deps=all"

diff  --git a/clang/test/Modules/dependency-gen-direct-module-deps.m 
b/clang/test/Modules/dependency-gen-direct-module-deps.m
new file mode 100644
index 0000000000000..81a856ff0e81e
--- /dev/null
+++ b/clang/test/Modules/dependency-gen-direct-module-deps.m
@@ -0,0 +1,34 @@
+// RUN: rm -rf %t-mcp
+// RUN: mkdir -p %t-mcp
+// REQUIRES: x86-registered-target
+
+// Check that -module-file-deps=direct only includes directly imported PCMs,
+// not transitive ones.
+
+// RUN: %clang_cc1 -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 \
+// RUN:   -module-file-deps=direct -dependency-file %t.d -MT %s.o \
+// RUN:   -I %S/Inputs -fmodules -fimplicit-module-maps -fdisable-module-hash \
+// RUN:   -fmodules-cache-path=%t-mcp -fsyntax-only %s
+// RUN: FileCheck %s < %t.d
+
+// The directly imported module should appear.
+// CHECK: diamond_bottom.pcm
+
+// Transitive dependencies should not appear.
+// CHECK-NOT: diamond_left.pcm
+// CHECK-NOT: diamond_right.pcm
+// CHECK-NOT: diamond_top.pcm
+
+// -module-file-deps=all includes all transitive PCMs to show they all are 
used.
+// RUN: %clang_cc1 -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 \
+// RUN:   -module-file-deps=all -dependency-file %t-all.d -MT %s.o \
+// RUN:   -I %S/Inputs -fmodules -fimplicit-module-maps -fdisable-module-hash \
+// RUN:   -fmodules-cache-path=%t-mcp -fsyntax-only %s
+// RUN: FileCheck --check-prefix=ALL %s < %t-all.d
+
+// ALL-DAG: diamond_bottom.pcm
+// ALL-DAG: diamond_left.pcm
+// ALL-DAG: diamond_right.pcm
+// ALL-DAG: diamond_top.pcm
+
+@import diamond_bottom;

diff  --git a/clang/test/Modules/dependency-gen-pch.m 
b/clang/test/Modules/dependency-gen-pch.m
index bdc226ffe33c8..145bb1eccfbef 100644
--- a/clang/test/Modules/dependency-gen-pch.m
+++ b/clang/test/Modules/dependency-gen-pch.m
@@ -2,7 +2,7 @@
 // RUN: mkdir -p %t-mcp
 // REQUIRES: x86-registered-target
 
-// RUN: %clang_cc1 -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 
-module-file-deps -dependency-file %t.d -MT %s.o -I %S/Inputs -fmodules 
-fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t-mcp 
-emit-pch -o %t.pch %s
+// RUN: %clang_cc1 -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 
-module-file-deps=all -dependency-file %t.d -MT %s.o -I %S/Inputs -fmodules 
-fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t-mcp 
-emit-pch -o %t.pch %s
 // RUN: FileCheck %s < %t.d
 // CHECK: dependency-gen-pch.m.o
 // CHECK-NEXT: dependency-gen-pch.m


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to