[clang] 17c2948 - [clang-scan-deps] Add an API for clang dependency scanner to perform

Akira Hatanaka via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 9 08:53:09 PDT 2021


Author: Akira Hatanaka
Date: 2021-09-09T08:52:50-07:00
New Revision: 17c2948d04431e94376e8d7883b5d89fbe705b5e

URL: https://github.com/llvm/llvm-project/commit/17c2948d04431e94376e8d7883b5d89fbe705b5e
DIFF: https://github.com/llvm/llvm-project/commit/17c2948d04431e94376e8d7883b5d89fbe705b5e.diff

LOG: [clang-scan-deps] Add an API for clang dependency scanner to perform
module lookup by name alone

This removes the need to create a fake source file that imports a
module.

rdar://64538073

Differential Revision: https://reviews.llvm.org/D109485

Added: 
    clang/test/ClangScanDeps/Inputs/modules_cdb_by_mod_name.json
    clang/test/ClangScanDeps/Inputs/modules_cdb_clangcl_by_mod_name.json
    clang/test/ClangScanDeps/modules-full-by-mod-name.cpp

Modified: 
    clang/include/clang/Frontend/FrontendActions.h
    clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h
    clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
    clang/lib/Frontend/FrontendActions.cpp
    clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp
    clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
    clang/tools/clang-scan-deps/ClangScanDeps.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Frontend/FrontendActions.h b/clang/include/clang/Frontend/FrontendActions.h
index ff8d4417eaa49..545a7e842c4ff 100644
--- a/clang/include/clang/Frontend/FrontendActions.h
+++ b/clang/include/clang/Frontend/FrontendActions.h
@@ -299,6 +299,15 @@ class PrintPreprocessedAction : public PreprocessorFrontendAction {
   bool hasPCHSupport() const override { return true; }
 };
 
+class GetDependenciesByModuleNameAction : public PreprocessOnlyAction {
+  StringRef ModuleName;
+  void ExecuteAction() override;
+
+public:
+  GetDependenciesByModuleNameAction(StringRef ModuleName)
+      : ModuleName(ModuleName) {}
+};
+
 }  // end namespace clang
 
 #endif

diff  --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h
index f88dc472c80b1..c26b6e91d90ce 100644
--- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h
+++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h
@@ -77,16 +77,18 @@ class DependencyScanningTool {
 
   /// Print out the dependency information into a string using the dependency
   /// file format that is specified in the options (-MD is the default) and
-  /// return it.
+  /// return it. If \p ModuleName isn't empty, this function returns the
+  /// dependency information of module \p ModuleName.
   ///
   /// \returns A \c StringError with the diagnostic output if clang errors
   /// occurred, dependency file contents otherwise.
   llvm::Expected<std::string>
   getDependencyFile(const tooling::CompilationDatabase &Compilations,
-                    StringRef CWD);
+                    StringRef CWD, llvm::Optional<StringRef> ModuleName = None);
 
   /// Collect the full module dependency graph for the input, ignoring any
-  /// modules which have already been seen.
+  /// modules which have already been seen. If \p ModuleName isn't empty, this
+  /// function returns the full dependency information of module \p ModuleName.
   ///
   /// \param AlreadySeen This stores modules which have previously been
   ///                    reported. Use the same instance for all calls to this
@@ -98,7 +100,8 @@ class DependencyScanningTool {
   /// occurred, \c FullDependencies otherwise.
   llvm::Expected<FullDependenciesResult>
   getFullDependencies(const tooling::CompilationDatabase &Compilations,
-                      StringRef CWD, const llvm::StringSet<> &AlreadySeen);
+                      StringRef CWD, const llvm::StringSet<> &AlreadySeen,
+                      llvm::Optional<StringRef> ModuleName = None);
 
 private:
   DependencyScanningWorker Worker;

diff  --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
index c6f7d239b8eb5..3ae3bcda72392 100644
--- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
+++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
@@ -76,14 +76,16 @@ class DependencyScanningWorker {
 
   /// Run the dependency scanning tool for a given clang driver invocation (as
   /// specified for the given Input in the CDB), and report the discovered
-  /// dependencies to the provided consumer.
+  /// dependencies to the provided consumer. If \p ModuleName isn't empty, this
+  /// function reports the dependencies of module \p ModuleName.
   ///
   /// \returns A \c StringError with the diagnostic output if clang errors
   /// occurred, success otherwise.
   llvm::Error computeDependencies(const std::string &Input,
                                   StringRef WorkingDirectory,
                                   const CompilationDatabase &CDB,
-                                  DependencyConsumer &Consumer);
+                                  DependencyConsumer &Consumer,
+                                  llvm::Optional<StringRef> ModuleName = None);
 
 private:
   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;

diff  --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index c6ebbdc8c04e1..b5544afa9f248 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -993,3 +993,17 @@ void PrintDependencyDirectivesSourceMinimizerAction::ExecuteAction() {
   }
   llvm::outs() << Output;
 }
+
+void GetDependenciesByModuleNameAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+  Preprocessor &PP = CI.getPreprocessor();
+  SourceManager &SM = PP.getSourceManager();
+  FileID MainFileID = SM.getMainFileID();
+  SourceLocation FileStart = SM.getLocForStartOfFile(MainFileID);
+  SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;
+  IdentifierInfo *ModuleID = PP.getIdentifierInfo(ModuleName);
+  Path.push_back(std::make_pair(ModuleID, FileStart));
+  auto ModResult = CI.loadModule(FileStart, Path, Module::Hidden, false);
+  PPCallbacks *CB = PP.getPPCallbacks();
+  CB->moduleImport(SourceLocation(), Path, ModResult);
+}

diff  --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp
index 43b6a0c95f047..a7969b358d9cc 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp
@@ -50,7 +50,8 @@ DependencyScanningTool::DependencyScanningTool(
     : Worker(Service) {}
 
 llvm::Expected<std::string> DependencyScanningTool::getDependencyFile(
-    const tooling::CompilationDatabase &Compilations, StringRef CWD) {
+    const tooling::CompilationDatabase &Compilations, StringRef CWD,
+    llvm::Optional<StringRef> ModuleName) {
   /// Prints out all of the gathered dependencies into a string.
   class MakeDependencyPrinterConsumer : public DependencyConsumer {
   public:
@@ -112,7 +113,8 @@ llvm::Expected<std::string> DependencyScanningTool::getDependencyFile(
   std::string Input = Compilations.getAllCompileCommands().front().Filename;
 
   MakeDependencyPrinterConsumer Consumer;
-  auto Result = Worker.computeDependencies(Input, CWD, Compilations, Consumer);
+  auto Result = Worker.computeDependencies(Input, CWD, Compilations, Consumer,
+                                           ModuleName);
   if (Result)
     return std::move(Result);
   std::string Output;
@@ -123,7 +125,8 @@ llvm::Expected<std::string> DependencyScanningTool::getDependencyFile(
 llvm::Expected<FullDependenciesResult>
 DependencyScanningTool::getFullDependencies(
     const tooling::CompilationDatabase &Compilations, StringRef CWD,
-    const llvm::StringSet<> &AlreadySeen) {
+    const llvm::StringSet<> &AlreadySeen,
+    llvm::Optional<StringRef> ModuleName) {
   class FullDependencyPrinterConsumer : public DependencyConsumer {
   public:
     FullDependencyPrinterConsumer(const llvm::StringSet<> &AlreadySeen)
@@ -196,8 +199,8 @@ DependencyScanningTool::getFullDependencies(
   std::string Input = Compilations.getAllCompileCommands().front().Filename;
 
   FullDependencyPrinterConsumer Consumer(AlreadySeen);
-  llvm::Error Result =
-      Worker.computeDependencies(Input, CWD, Compilations, Consumer);
+  llvm::Error Result = Worker.computeDependencies(Input, CWD, Compilations,
+                                                  Consumer, ModuleName);
   if (Result)
     return std::move(Result);
   return Consumer.getFullDependencies();

diff  --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
index d651ff23b387a..10385ab356692 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -141,10 +141,11 @@ class DependencyScanningAction : public tooling::ToolAction {
       StringRef WorkingDirectory, DependencyConsumer &Consumer,
       llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS,
       ExcludedPreprocessorDirectiveSkipMapping *PPSkipMappings,
-      ScanningOutputFormat Format)
+      ScanningOutputFormat Format, llvm::Optional<StringRef> ModuleName = None,
+      llvm::Optional<llvm::MemoryBufferRef> FakeMemBuffer = None)
       : WorkingDirectory(WorkingDirectory), Consumer(Consumer),
-        DepFS(std::move(DepFS)), PPSkipMappings(PPSkipMappings),
-        Format(Format) {}
+        DepFS(std::move(DepFS)), PPSkipMappings(PPSkipMappings), Format(Format),
+        ModuleName(ModuleName), FakeMemBuffer(FakeMemBuffer) {}
 
   bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
                      FileManager *FileMgr,
@@ -214,6 +215,16 @@ class DependencyScanningAction : public tooling::ToolAction {
             .ExcludedConditionalDirectiveSkipMappings = PPSkipMappings;
     }
 
+    if (ModuleName.hasValue()) {
+      SmallString<128> FullPath(*ModuleName);
+      llvm::sys::fs::make_absolute(WorkingDirectory, FullPath);
+      SourceManager &SrcMgr = Compiler.getSourceManager();
+      FileMgr->getVirtualFile(FullPath.c_str(), FakeMemBuffer->getBufferSize(),
+                              0);
+      FileID MainFileID = SrcMgr.createFileID(*FakeMemBuffer);
+      SrcMgr.setMainFileID(MainFileID);
+    }
+
     // Create the dependency collector that will collect the produced
     // dependencies.
     //
@@ -249,7 +260,13 @@ class DependencyScanningAction : public tooling::ToolAction {
     // the impact of strict context hashing.
     Compiler.getHeaderSearchOpts().ModulesStrictContextHash = true;
 
-    auto Action = std::make_unique<ReadPCHAndPreprocessAction>();
+    std::unique_ptr<FrontendAction> Action;
+
+    if (ModuleName.hasValue())
+      Action = std::make_unique<GetDependenciesByModuleNameAction>(*ModuleName);
+    else
+      Action = std::make_unique<ReadPCHAndPreprocessAction>();
+
     const bool Result = Compiler.ExecuteAction(*Action);
     if (!DepFS)
       FileMgr->clearStatCache();
@@ -262,6 +279,8 @@ class DependencyScanningAction : public tooling::ToolAction {
   llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS;
   ExcludedPreprocessorDirectiveSkipMapping *PPSkipMappings;
   ScanningOutputFormat Format;
+  llvm::Optional<StringRef> ModuleName;
+  llvm::Optional<llvm::MemoryBufferRef> FakeMemBuffer;
 };
 
 } // end anonymous namespace
@@ -307,19 +326,42 @@ static llvm::Error runWithDiags(
 
 llvm::Error DependencyScanningWorker::computeDependencies(
     const std::string &Input, StringRef WorkingDirectory,
-    const CompilationDatabase &CDB, DependencyConsumer &Consumer) {
+    const CompilationDatabase &CDB, DependencyConsumer &Consumer,
+    llvm::Optional<StringRef> ModuleName) {
   RealFS->setCurrentWorkingDirectory(WorkingDirectory);
+  std::unique_ptr<llvm::MemoryBuffer> FakeMemBuffer =
+      ModuleName.hasValue() ? llvm::MemoryBuffer::getMemBuffer(" ") : nullptr;
   return runWithDiags(DiagOpts.get(), [&](DiagnosticConsumer &DC) {
     /// Create the tool that uses the underlying file system to ensure that any
     /// file system requests that are made by the driver do not go through the
     /// dependency scanning filesystem.
-    tooling::ClangTool Tool(CDB, Input, PCHContainerOps, RealFS, Files);
+    SmallString<128> FullPath;
+    tooling::ClangTool Tool(CDB,
+                            ModuleName.hasValue() ? ModuleName->str() : Input,
+                            PCHContainerOps, RealFS, Files);
     Tool.clearArgumentsAdjusters();
     Tool.setRestoreWorkingDir(false);
     Tool.setPrintErrorMessage(false);
     Tool.setDiagnosticConsumer(&DC);
-    DependencyScanningAction Action(WorkingDirectory, Consumer, DepFS,
-                                    PPSkipMappings.get(), Format);
+    DependencyScanningAction Action(
+        WorkingDirectory, Consumer, DepFS, PPSkipMappings.get(), Format,
+        ModuleName,
+        FakeMemBuffer
+            ? llvm::Optional<llvm::MemoryBufferRef>(*FakeMemBuffer.get())
+            : None);
+
+    if (ModuleName.hasValue()) {
+      Tool.mapVirtualFile(*ModuleName, FakeMemBuffer->getBuffer());
+      FullPath = *ModuleName;
+      llvm::sys::fs::make_absolute(WorkingDirectory, FullPath);
+      Tool.appendArgumentsAdjuster(
+          [&](const tooling::CommandLineArguments &Args, StringRef FileName) {
+            tooling::CommandLineArguments AdjustedArgs(Args);
+            AdjustedArgs.push_back(std::string(FullPath));
+            return AdjustedArgs;
+          });
+    }
+
     return !Tool.run(&Action);
   });
 }

diff  --git a/clang/test/ClangScanDeps/Inputs/modules_cdb_by_mod_name.json b/clang/test/ClangScanDeps/Inputs/modules_cdb_by_mod_name.json
new file mode 100644
index 0000000000000..f95749f11be2a
--- /dev/null
+++ b/clang/test/ClangScanDeps/Inputs/modules_cdb_by_mod_name.json
@@ -0,0 +1,12 @@
+[
+{
+  "directory": "DIR",
+  "command": "clang -E -IInputs -D INCLUDE_HEADER2 -MD -MF DIR/modules_cdb2.d -fmodules -fcxx-modules -fmodules-cache-path=DIR/module-cache -fimplicit-modules -fimplicit-module-maps -gmodules -x c++",
+  "file": ""
+},
+{
+  "directory": "DIR",
+  "command": "clang -E -IInputs -fmodules -fcxx-modules -fmodules-cache-path=DIR/module-cache -fimplicit-modules -fimplicit-module-maps -x c++",
+  "file": ""
+},
+]

diff  --git a/clang/test/ClangScanDeps/Inputs/modules_cdb_clangcl_by_mod_name.json b/clang/test/ClangScanDeps/Inputs/modules_cdb_clangcl_by_mod_name.json
new file mode 100644
index 0000000000000..ef44985a8f915
--- /dev/null
+++ b/clang/test/ClangScanDeps/Inputs/modules_cdb_clangcl_by_mod_name.json
@@ -0,0 +1,12 @@
+[
+{
+  "directory": "DIR",
+  "command": "clang-cl /E /IInputs /D INCLUDE_HEADER2 /clang:-MD /clang:-MF /clang:DIR/modules_cdb2_clangcl.d /clang:-fmodules /clang:-fcxx-modules /clang:-fmodules-cache-path=DIR/module-cache_clangcl /clang:-fimplicit-modules /clang:-fimplicit-module-maps /clang:-x /clang:c++ --",
+  "file": ""
+},
+{
+  "directory": "DIR",
+  "command": "clang-cl /E /IInputs /clang:-fmodules /clang:-fcxx-modules /clang:-fmodules-cache-path=DIR/module-cache_clangcl /clang:-fimplicit-modules /clang:-fimplicit-module-maps /clang:-x /clang:c++ --",
+  "file": ""
+},
+]

diff  --git a/clang/test/ClangScanDeps/modules-full-by-mod-name.cpp b/clang/test/ClangScanDeps/modules-full-by-mod-name.cpp
new file mode 100644
index 0000000000000..cecc76840e1d5
--- /dev/null
+++ b/clang/test/ClangScanDeps/modules-full-by-mod-name.cpp
@@ -0,0 +1,79 @@
+// RUN: rm -rf %t.dir
+// RUN: rm -rf %t.cdb
+// RUN: mkdir -p %t.dir
+// RUN: cp %s %t.dir/modules_cdb_input.cpp
+// RUN: cp %s %t.dir/modules_cdb_input2.cpp
+// RUN: mkdir %t.dir/Inputs
+// RUN: cp %S/Inputs/header.h %t.dir/Inputs/header.h
+// RUN: cp %S/Inputs/header2.h %t.dir/Inputs/header2.h
+// RUN: cp %S/Inputs/module.modulemap %t.dir/Inputs/module.modulemap
+// RUN: sed -e "s|DIR|%/t.dir|g" %S/Inputs/modules_cdb_by_mod_name.json > %t.cdb
+// RUN: sed -e "s|DIR|%/t.dir|g" %S/Inputs/modules_cdb_clangcl_by_mod_name.json > %t_clangcl.cdb
+//
+// RUN: echo %t.dir > %t.result
+// RUN: clang-scan-deps -compilation-database %t.cdb -j 4 -format experimental-full \
+// RUN:   -mode preprocess-minimized-sources -module-name=header1 >> %t.result
+// RUN: cat %t.result | sed 's:\\\\\?:/:g' | FileCheck --check-prefixes=CHECK %s
+//
+// RUN: echo %t.dir > %t_clangcl.result
+// RUN: clang-scan-deps -compilation-database %t_clangcl.cdb -j 4 -format experimental-full \
+// RUN:   -mode preprocess-minimized-sources -module-name=header1 >> %t_clangcl.result
+// RUN: cat %t_clangcl.result | sed 's:\\\\\?:/:g' | FileCheck --check-prefixes=CHECK %s
+
+// CHECK: [[PREFIX:.*]]
+// CHECK-NEXT: {
+// CHECK-NEXT:   "modules": [
+// CHECK-NEXT:     {
+// CHECK-NEXT:       "clang-module-deps": [
+// CHECK-NEXT:         {
+// CHECK-NEXT:           "context-hash": "[[HASH_H2_DINCLUDE:[A-Z0-9]+]]",
+// CHECK-NEXT:           "module-name": "header2"
+// CHECK-NEXT:         }
+// CHECK-NEXT:       ],
+// CHECK-NEXT:       "clang-modulemap-file": "[[PREFIX]]/Inputs/module.modulemap",
+// CHECK-NEXT:       "command-line": [
+// CHECK-NEXT:         "-cc1"
+// CHECK:              "-emit-module"
+// CHECK:              "-fmodule-name=header1"
+// CHECK:              "-fno-implicit-modules"
+// CHECK:            ],
+// CHECK-NEXT:       "context-hash": "[[HASH_H1_DINCLUDE:[A-Z0-9]+]]",
+// CHECK-NEXT:       "file-deps": [
+// CHECK-NEXT:         "[[PREFIX]]/Inputs/header.h",
+// CHECK-NEXT:         "[[PREFIX]]/Inputs/module.modulemap"
+// CHECK-NEXT:       ],
+// CHECK-NEXT:       "name": "header1"
+// CHECK-NEXT:     },
+// CHECK-NEXT:     {
+// CHECK-NEXT:       "clang-module-deps": [],
+// CHECK-NEXT:       "clang-modulemap-file": "[[PREFIX]]/Inputs/module.modulemap",
+// CHECK-NEXT:       "command-line": [
+// CHECK-NEXT:         "-cc1",
+// CHECK:              "-emit-module",
+// CHECK:              "-fmodule-name=header1",
+// CHECK:              "-fno-implicit-modules",
+// CHECK:            ],
+// CHECK-NEXT:       "context-hash": "[[HASH_H1:[A-Z0-9]+]]",
+// CHECK-NEXT:       "file-deps": [
+// CHECK-NEXT:         "[[PREFIX]]/Inputs/header.h",
+// CHECK-NEXT:         "[[PREFIX]]/Inputs/module.modulemap"
+// CHECK-NEXT:       ],
+// CHECK-NEXT:       "name": "header1"
+// CHECK-NEXT:     },
+// CHECK-NEXT:     {
+// CHECK-NEXT:       "clang-module-deps": [],
+// CHECK-NEXT:       "clang-modulemap-file": "[[PREFIX]]/Inputs/module.modulemap",
+// CHECK-NEXT:       "command-line": [
+// CHECK-NEXT:         "-cc1",
+// CHECK:              "-emit-module",
+// CHECK:              "-fmodule-name=header2",
+// CHECK:              "-fno-implicit-modules",
+// CHECK:            ],
+// CHECK-NEXT:       "context-hash": "[[HASH_H2_DINCLUDE]]",
+// CHECK-NEXT:       "file-deps": [
+// CHECK-NEXT:         "[[PREFIX]]/Inputs/header2.h",
+// CHECK-NEXT:         "[[PREFIX]]/Inputs/module.modulemap"
+// CHECK-NEXT:       ],
+// CHECK-NEXT:       "name": "header2"
+// CHECK-NEXT:     }
+// CHECK-NEXT:   ],

diff  --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
index 92b9bdd83e396..d3630c94b5bf2 100644
--- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp
+++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp
@@ -194,6 +194,11 @@ llvm::cl::opt<bool> SkipExcludedPPRanges(
         "until reaching the end directive."),
     llvm::cl::init(true), llvm::cl::cat(DependencyScannerCategory));
 
+llvm::cl::opt<std::string> ModuleName(
+    "module-name", llvm::cl::Optional,
+    llvm::cl::desc("the module of which the dependencies are to be computed"),
+    llvm::cl::cat(DependencyScannerCategory));
+
 llvm::cl::opt<bool> Verbose("v", llvm::cl::Optional,
                             llvm::cl::desc("Use verbose output."),
                             llvm::cl::init(false),
@@ -544,13 +549,20 @@ int main(int argc, const char **argv) {
         }
         // Run the tool on it.
         if (Format == ScanningOutputFormat::Make) {
-          auto MaybeFile = WorkerTools[I]->getDependencyFile(*Input, CWD);
+          auto MaybeFile = WorkerTools[I]->getDependencyFile(
+              *Input, CWD,
+              ModuleName.empty()
+                  ? None
+                  : llvm::Optional<StringRef>(ModuleName.c_str()));
           if (handleMakeDependencyToolResult(Filename, MaybeFile, DependencyOS,
                                              Errs))
             HadErrors = true;
         } else {
           auto MaybeFullDeps = WorkerTools[I]->getFullDependencies(
-              *Input, CWD, AlreadySeenModules);
+              *Input, CWD, AlreadySeenModules,
+              ModuleName.empty()
+                  ? None
+                  : llvm::Optional<StringRef>(ModuleName.c_str()));
           if (handleFullDependencyToolResult(Filename, MaybeFullDeps, FD,
                                              LocalIndex, DependencyOS, Errs))
             HadErrors = true;


        


More information about the cfe-commits mailing list