]> granicus.if.org Git - clang/commitdiff
[clang-scan-deps] reuse the file manager across invocations of
authorAlex Lorenz <arphaman@gmail.com>
Thu, 29 Aug 2019 22:56:38 +0000 (22:56 +0000)
committerAlex Lorenz <arphaman@gmail.com>
Thu, 29 Aug 2019 22:56:38 +0000 (22:56 +0000)
the dependency scanner on a single worker thread

This behavior can be controlled using the new `-reuse-filemanager` clang-scan-deps
option. By default the file manager is reused.

The added test/ClangScanDeps/symlink.cpp is able to pass with
the reused filemanager after the related FileEntryRef changes
landed earlier. The test test/ClangScanDeps/subframework_header_dir_symlink.m
still fails when the file manager is reused (I run the FileCheck with not to
make it PASS). I will address this in a follow-up patch that improves
the DirectoryEntry name modelling in the FileManager.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@370420 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Tooling/DependencyScanning/DependencyScanningService.h
include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
include/clang/Tooling/Tooling.h
lib/Tooling/DependencyScanning/DependencyScanningService.cpp
lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
lib/Tooling/Tooling.cpp
test/ClangScanDeps/Inputs/subframework_header_dir_symlink_cdb.json [new file with mode: 0644]
test/ClangScanDeps/Inputs/symlink_cdb.json [new file with mode: 0644]
test/ClangScanDeps/subframework_header_dir_symlink.m [new file with mode: 0644]
test/ClangScanDeps/symlink.cpp [new file with mode: 0644]
tools/clang-scan-deps/ClangScanDeps.cpp

index 0dde0ad35df20b7d9ad37ceaaf6871062110bef6..c49f92d082c207e8cc0c32b560a00a5db6dfd760 100644 (file)
@@ -34,16 +34,19 @@ enum class ScanningMode {
 /// the invidual dependency scanning workers.
 class DependencyScanningService {
 public:
-  DependencyScanningService(ScanningMode Mode);
+  DependencyScanningService(ScanningMode Mode, bool ReuseFileManager = true);
 
   ScanningMode getMode() const { return Mode; }
 
+  bool canReuseFileManager() const { return ReuseFileManager; }
+
   DependencyScanningFilesystemSharedCache &getSharedCache() {
     return SharedCache;
   }
 
 private:
   const ScanningMode Mode;
+  const bool ReuseFileManager;
   /// The global file system cache.
   DependencyScanningFilesystemSharedCache SharedCache;
 };
index 79c652ef5a9c30aa818eb11be922199247c7dc21..d56f5395da167e213310900fced4f9b4c8ee7212 100644 (file)
@@ -54,6 +54,9 @@ private:
   /// dependencies. This filesystem persists accross multiple compiler
   /// invocations.
   llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS;
+  /// The file manager that is reused accross multiple invocations by this
+  /// worker. If null, the file manager will not be reused.
+  llvm::IntrusiveRefCntPtr<FileManager> Files;
 };
 
 } // end namespace dependencies
index 5df816e671533f4dd3b649dcb821e00f063838ab..b8c7435c5e220eb0cdbe37e5bad430c92081994f 100644 (file)
@@ -349,12 +349,15 @@ public:
   /// clang modules.
   /// \param BaseFS VFS used for all underlying file accesses when running the
   /// tool.
+  /// \param Files The file manager to use for underlying file operations when
+  /// running the tool.
   ClangTool(const CompilationDatabase &Compilations,
             ArrayRef<std::string> SourcePaths,
             std::shared_ptr<PCHContainerOperations> PCHContainerOps =
                 std::make_shared<PCHContainerOperations>(),
             IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS =
-                llvm::vfs::getRealFileSystem());
+                llvm::vfs::getRealFileSystem(),
+            IntrusiveRefCntPtr<FileManager> Files = nullptr);
 
   ~ClangTool();
 
index 48aa68218c3ea1c835886f7ef2075fe077066675..6ddce0dcee85a0b30dd71416d12305bf1fad5b33 100644 (file)
@@ -12,5 +12,6 @@ using namespace clang;
 using namespace tooling;
 using namespace dependencies;
 
-DependencyScanningService::DependencyScanningService(ScanningMode Mode)
-    : Mode(Mode) {}
+DependencyScanningService::DependencyScanningService(ScanningMode Mode,
+                                                     bool ReuseFileManager)
+    : Mode(Mode), ReuseFileManager(ReuseFileManager) {}
index c80a55645eb974a06c73dca925e83ff582292ca4..2d49e0d794af6086363ae08f48f40b140de40651 100644 (file)
@@ -148,6 +148,8 @@ DependencyScanningWorker::DependencyScanningWorker(
   if (Service.getMode() == ScanningMode::MinimizedSourcePreprocessing)
     DepFS = new DependencyScanningWorkerFilesystem(Service.getSharedCache(),
                                                    RealFS);
+  if (Service.canReuseFileManager())
+    Files = new FileManager(FileSystemOptions(), RealFS);
 }
 
 llvm::Expected<std::string>
@@ -164,7 +166,7 @@ DependencyScanningWorker::getDependencyFile(const std::string &Input,
   /// 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);
+  tooling::ClangTool Tool(CDB, Input, PCHContainerOps, RealFS, Files);
   Tool.clearArgumentsAdjusters();
   Tool.setRestoreWorkingDir(false);
   Tool.setPrintErrorMessage(false);
index 8c0d13d243d1877b03f263800ffb920a9c8dfcb2..472a3ab57c3325bcd62ed563007ea5c02ad08752 100644 (file)
@@ -378,16 +378,20 @@ bool FrontendActionFactory::runInvocation(
 ClangTool::ClangTool(const CompilationDatabase &Compilations,
                      ArrayRef<std::string> SourcePaths,
                      std::shared_ptr<PCHContainerOperations> PCHContainerOps,
-                     IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS)
+                     IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
+                     IntrusiveRefCntPtr<FileManager> Files)
     : Compilations(Compilations), SourcePaths(SourcePaths),
       PCHContainerOps(std::move(PCHContainerOps)),
       OverlayFileSystem(new llvm::vfs::OverlayFileSystem(std::move(BaseFS))),
       InMemoryFileSystem(new llvm::vfs::InMemoryFileSystem),
-      Files(new FileManager(FileSystemOptions(), OverlayFileSystem)) {
+      Files(Files ? Files
+                  : new FileManager(FileSystemOptions(), OverlayFileSystem)) {
   OverlayFileSystem->pushOverlay(InMemoryFileSystem);
   appendArgumentsAdjuster(getClangStripOutputAdjuster());
   appendArgumentsAdjuster(getClangSyntaxOnlyAdjuster());
   appendArgumentsAdjuster(getClangStripDependencyFileAdjuster());
+  if (Files)
+    Files->setVirtualFileSystem(OverlayFileSystem);
 }
 
 ClangTool::~ClangTool() = default;
diff --git a/test/ClangScanDeps/Inputs/subframework_header_dir_symlink_cdb.json b/test/ClangScanDeps/Inputs/subframework_header_dir_symlink_cdb.json
new file mode 100644 (file)
index 0000000..a405c6b
--- /dev/null
@@ -0,0 +1,12 @@
+[
+{
+  "directory": "DIR",
+  "command": "clang -E DIR/subframework_header_dir_symlink.m -D EMPTY -iframework Inputs/frameworks",
+  "file": "DIR/subframework_header_dir_symlink.m"
+},
+{
+  "directory": "DIR",
+  "command": "clang -E DIR/subframework_header_dir_symlink2.m -FInputs/frameworks_symlink -iframework Inputs/frameworks",
+  "file": "DIR/subframework_header_dir_symlink2.m"
+}
+]
diff --git a/test/ClangScanDeps/Inputs/symlink_cdb.json b/test/ClangScanDeps/Inputs/symlink_cdb.json
new file mode 100644 (file)
index 0000000..43bb418
--- /dev/null
@@ -0,0 +1,12 @@
+[
+{
+  "directory": "DIR",
+  "command": "clang -E DIR/symlink.cpp -IInputs",
+  "file": "DIR/symlink.cpp"
+},
+{
+  "directory": "DIR",
+  "command": "clang -E DIR/symlink2.cpp -IInputs",
+  "file": "DIR/symlink2.cpp"
+}
+]
diff --git a/test/ClangScanDeps/subframework_header_dir_symlink.m b/test/ClangScanDeps/subframework_header_dir_symlink.m
new file mode 100644 (file)
index 0000000..5cc1785
--- /dev/null
@@ -0,0 +1,25 @@
+// REQUIRES: shell
+// RUN: rm -rf %t.dir
+// RUN: rm -rf %t.cdb
+// RUN: mkdir -p %t.dir
+// RUN: cp %s %t.dir/subframework_header_dir_symlink.m
+// RUN: cp %s %t.dir/subframework_header_dir_symlink2.m
+// RUN: mkdir %t.dir/Inputs
+// RUN: cp -R %S/Inputs/frameworks %t.dir/Inputs/frameworks
+// RUN: ln -s %t.dir/Inputs/frameworks %t.dir/Inputs/frameworks_symlink
+// RUN: sed -e "s|DIR|%/t.dir|g" %S/Inputs/subframework_header_dir_symlink_cdb.json > %t.cdb
+// RUN: clang-scan-deps -compilation-database %t.cdb -j 1  -reuse-filemanager=0 | \
+// RUN:   FileCheck %s
+// FIXME: Make this work when the filemanager is reused:
+// RUN: clang-scan-deps -compilation-database %t.cdb -j 1 -reuse-filemanager=1 | \
+// RUN:   not FileCheck %s
+
+#ifndef EMPTY
+#include "Framework/Framework.h"
+#endif
+
+// CHECK: clang-scan-deps dependency
+// CHECK-NEXT: subframework_header_dir_symlink.m
+// CHECK: clang-scan-deps dependency
+// CHECK-NEXT: subframework_header_dir_symlink.m
+// CHECK-NEXT: Inputs{{/|\\}}frameworks_symlink{{/|\\}}Framework.framework{{/|\\}}Headers{{/|\\}}Framework.h
diff --git a/test/ClangScanDeps/symlink.cpp b/test/ClangScanDeps/symlink.cpp
new file mode 100644 (file)
index 0000000..e1a6ac9
--- /dev/null
@@ -0,0 +1,23 @@
+// REQUIRES: shell
+// RUN: rm -rf %t.dir
+// RUN: rm -rf %t.cdb
+// RUN: mkdir -p %t.dir
+// RUN: cp %s %t.dir/symlink.cpp
+// RUN: cp %s %t.dir/symlink2.cpp
+// RUN: mkdir %t.dir/Inputs
+// RUN: cp %S/Inputs/header.h %t.dir/Inputs/header.h
+// RUN: ln -s %t.dir/Inputs/header.h %t.dir/Inputs/symlink.h
+// RUN: sed -e "s|DIR|%/t.dir|g" %S/Inputs/symlink_cdb.json > %t.cdb
+// RUN: clang-scan-deps -compilation-database %t.cdb -j 1 -reuse-filemanager=0 | FileCheck %s
+// RUN: clang-scan-deps -compilation-database %t.cdb -j 1 -reuse-filemanager=1 | FileCheck %s
+
+#include "symlink.h"
+#include "header.h"
+
+// CHECK: symlink.cpp
+// CHECK-NEXT: Inputs{{/|\\}}symlink.h
+// CHECK-NEXT: Inputs{{/|\\}}header.h
+
+// CHECK: symlink2.cpp
+// CHECK-NEXT: Inputs{{/|\\}}symlink.h
+// CHECK-NEXT: Inputs{{/|\\}}header.h
index b838845c4484dcfba2f868d20e686422e906f1d2..5e567fef9dae36c5e64e043239945021d4f5de5a 100644 (file)
@@ -107,6 +107,11 @@ llvm::cl::opt<std::string>
                   llvm::cl::desc("Compilation database"), llvm::cl::Required,
                   llvm::cl::cat(DependencyScannerCategory));
 
+llvm::cl::opt<bool> ReuseFileManager(
+    "reuse-filemanager",
+    llvm::cl::desc("Reuse the file manager and its cache between invocations."),
+    llvm::cl::init(true), llvm::cl::cat(DependencyScannerCategory));
+
 } // end anonymous namespace
 
 int main(int argc, const char **argv) {
@@ -153,7 +158,7 @@ int main(int argc, const char **argv) {
   // Print out the dependency results to STDOUT by default.
   SharedStream DependencyOS(llvm::outs());
 
-  DependencyScanningService Service(ScanMode);
+  DependencyScanningService Service(ScanMode, ReuseFileManager);
 #if LLVM_ENABLE_THREADS
   unsigned NumWorkers =
       NumThreads == 0 ? llvm::hardware_concurrency() : NumThreads;