This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG80c0c639687e: [clang][deps] Prevent unintended modifications 
of the original TU command-line (authored by jansvoboda11).

Changed prior to commit:
  https://reviews.llvm.org/D104036?vs=351174&id=351833#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D104036/new/

https://reviews.llvm.org/D104036

Files:
  clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
  clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
  clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
  clang/test/ClangScanDeps/Inputs/preserved-args/cdb.json.template
  clang/test/ClangScanDeps/Inputs/preserved-args/mod.h
  clang/test/ClangScanDeps/Inputs/preserved-args/module.modulemap
  clang/test/ClangScanDeps/Inputs/preserved-args/tu.c
  clang/test/ClangScanDeps/preserved-args.c

Index: clang/test/ClangScanDeps/preserved-args.c
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/preserved-args.c
@@ -0,0 +1,26 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: cp -r %S/Inputs/preserved-args/* %t
+// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.template > %t/cdb.json
+
+// RUN: echo -%t > %t/result.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
+
+// CHECK:      -[[PREFIX:.*]]
+// CHECK-NEXT: {
+// CHECK-NEXT:   "modules": [
+// CHECK-NEXT:     {
+// CHECK:            "command-line": [
+// CHECK-NEXT:         "-cc1"
+// CHECK:              "-serialize-diagnostic-file"
+// CHECK-NEXT:         "[[PREFIX]]/tu.dia"
+// CHECK:              "-fmodule-file=Foo=[[PREFIX]]/foo.pcm"
+// CHECK:              "-MT"
+// CHECK-NEXT:         "my_target"
+// CHECK:              "-dependency-file"
+// CHECK-NEXT:         "[[PREFIX]]/tu.d"
+// CHECK:            ],
+// CHECK:            "name": "Mod"
+// CHECK-NEXT:     }
+// CHECK-NEXT:   ]
+// CHECK:      }
Index: clang/test/ClangScanDeps/Inputs/preserved-args/tu.c
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/Inputs/preserved-args/tu.c
@@ -0,0 +1 @@
+#include "mod.h"
Index: clang/test/ClangScanDeps/Inputs/preserved-args/module.modulemap
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/Inputs/preserved-args/module.modulemap
@@ -0,0 +1,3 @@
+module Mod {
+  header "mod.h"
+}
Index: clang/test/ClangScanDeps/Inputs/preserved-args/mod.h
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/Inputs/preserved-args/mod.h
@@ -0,0 +1 @@
+// mod.h
Index: clang/test/ClangScanDeps/Inputs/preserved-args/cdb.json.template
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/Inputs/preserved-args/cdb.json.template
@@ -0,0 +1,7 @@
+[
+  {
+    "directory": "DIR",
+    "command": "clang -MD -MT my_target -serialize-diagnostics DIR/tu.dia -fsyntax-only DIR/tu.c -fmodules -fimplicit-module-maps -fmodules-cache-path=DIR/cache -fmodule-file=Foo=DIR/foo.pcm -o DIR/tu.o",
+    "file": "DIR/tu.c"
+  }
+]
Index: clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
===================================================================
--- clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
+++ clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
@@ -20,8 +20,8 @@
 
 CompilerInvocation ModuleDepCollector::makeInvocationForModuleBuildWithoutPaths(
     const ModuleDeps &Deps) const {
-  // Make a deep copy of the invocation.
-  CompilerInvocation CI(Instance.getInvocation());
+  // Make a deep copy of the original Clang invocation.
+  CompilerInvocation CI(OriginalInvocation);
 
   // Remove options incompatible with explicit module build.
   CI.getFrontendOpts().Inputs.clear();
@@ -39,9 +39,6 @@
     CI.getFrontendOpts().ModuleMapFiles.push_back(PrebuiltModule.ModuleMapFile);
   }
 
-  // Restore the original set of prebuilt module files.
-  CI.getHeaderSearchOpts().PrebuiltModuleFiles = OriginalPrebuiltModuleFiles;
-
   CI.getPreprocessorOpts().ImplicitPCHInclude.clear();
 
   return CI;
@@ -269,10 +266,9 @@
 
 ModuleDepCollector::ModuleDepCollector(
     std::unique_ptr<DependencyOutputOptions> Opts, CompilerInstance &I,
-    DependencyConsumer &C,
-    std::map<std::string, std::string, std::less<>> OriginalPrebuiltModuleFiles)
+    DependencyConsumer &C, CompilerInvocation &&OriginalCI)
     : Instance(I), Consumer(C), Opts(std::move(Opts)),
-      OriginalPrebuiltModuleFiles(std::move(OriginalPrebuiltModuleFiles)) {}
+      OriginalInvocation(std::move(OriginalCI)) {}
 
 void ModuleDepCollector::attachToPreprocessor(Preprocessor &PP) {
   PP.addPPCallbacks(std::make_unique<ModuleDepCollectorPP>(Instance, *this));
Index: clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
===================================================================
--- clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -47,9 +47,11 @@
 
 /// A listener that collects the names and paths to imported modules.
 class ImportCollectingListener : public ASTReaderListener {
+  using PrebuiltModuleFilesT =
+      decltype(HeaderSearchOptions::PrebuiltModuleFiles);
+
 public:
-  ImportCollectingListener(
-      std::map<std::string, std::string> &PrebuiltModuleFiles)
+  ImportCollectingListener(PrebuiltModuleFilesT &PrebuiltModuleFiles)
       : PrebuiltModuleFiles(PrebuiltModuleFiles) {}
 
   bool needsImportVisitation() const override { return true; }
@@ -59,7 +61,7 @@
   }
 
 private:
-  std::map<std::string, std::string> &PrebuiltModuleFiles;
+  PrebuiltModuleFilesT &PrebuiltModuleFiles;
 };
 
 /// Transform arbitrary file name into an object-like file name.
@@ -99,6 +101,9 @@
                      FileManager *FileMgr,
                      std::shared_ptr<PCHContainerOperations> PCHContainerOps,
                      DiagnosticConsumer *DiagConsumer) override {
+    // Make a deep copy of the original Clang invocation.
+    CompilerInvocation OriginalInvocation(*Invocation);
+
     // Create a compiler instance to handle the actual work.
     CompilerInstance Compiler(std::move(PCHContainerOps));
     Compiler.setInvocation(std::move(Invocation));
@@ -144,24 +149,19 @@
     Compiler.setFileManager(FileMgr);
     Compiler.createSourceManager(*FileMgr);
 
-    std::map<std::string, std::string> PrebuiltModuleFiles;
     if (!Compiler.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
-      /// Collect the modules that were prebuilt as part of the PCH.
-      ImportCollectingListener Listener(PrebuiltModuleFiles);
+      // Collect the modules that were prebuilt as part of the PCH and pass them
+      // to the compiler. This will prevent the implicit build to create
+      // duplicate modules and force reuse of existing prebuilt module files
+      // instead.
+      ImportCollectingListener Listener(
+          Compiler.getHeaderSearchOpts().PrebuiltModuleFiles);
       ASTReader::readASTFileControlBlock(
           Compiler.getPreprocessorOpts().ImplicitPCHInclude,
           Compiler.getFileManager(), Compiler.getPCHContainerReader(),
           /*FindModuleFileExtensions=*/false, Listener,
           /*ValidateDiagnosticOptions=*/false);
     }
-    /// Make a backup of the original prebuilt module file arguments.
-    std::map<std::string, std::string, std::less<>> OrigPrebuiltModuleFiles =
-        Compiler.getHeaderSearchOpts().PrebuiltModuleFiles;
-    /// Configure the compiler with discovered prebuilt modules. This will
-    /// prevent the implicit build of duplicate modules and force reuse of
-    /// existing prebuilt module files instead.
-    Compiler.getHeaderSearchOpts().PrebuiltModuleFiles.insert(
-        PrebuiltModuleFiles.begin(), PrebuiltModuleFiles.end());
 
     // Create the dependency collector that will collect the produced
     // dependencies.
@@ -187,8 +187,7 @@
       break;
     case ScanningOutputFormat::Full:
       Compiler.addDependencyCollector(std::make_shared<ModuleDepCollector>(
-          std::move(Opts), Compiler, Consumer,
-          std::move(OrigPrebuiltModuleFiles)));
+          std::move(Opts), Compiler, Consumer, std::move(OriginalInvocation)));
       break;
     }
 
Index: clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
===================================================================
--- clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
+++ clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
@@ -191,8 +191,7 @@
 public:
   ModuleDepCollector(std::unique_ptr<DependencyOutputOptions> Opts,
                      CompilerInstance &I, DependencyConsumer &C,
-                     std::map<std::string, std::string, std::less<>>
-                         OriginalPrebuiltModuleFiles);
+                     CompilerInvocation &&OriginalCI);
 
   void attachToPreprocessor(Preprocessor &PP) override;
   void attachToASTReader(ASTReader &R) override;
@@ -215,9 +214,8 @@
   std::unordered_map<const Module *, ModuleDeps> ModularDeps;
   /// Options that control the dependency output generation.
   std::unique_ptr<DependencyOutputOptions> Opts;
-  /// The mapping between prebuilt module names and module files that were
-  /// present in the original CompilerInvocation.
-  std::map<std::string, std::string, std::less<>> OriginalPrebuiltModuleFiles;
+  /// The original Clang invocation passed to dependency scanner.
+  CompilerInvocation OriginalInvocation;
 
   /// Checks whether the module is known as being prebuilt.
   bool isPrebuiltModule(const Module *M);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to