diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -137,11 +137,11 @@ DependencyScanningAction( StringRef WorkingDirectory, DependencyConsumer &Consumer, llvm::IntrusiveRefCntPtr DepFS, - ScanningOutputFormat Format, bool OptimizeArgs, + ScanningOutputFormat Format, bool OptimizeArgs, bool DisableFree, llvm::Optional ModuleName = None) : WorkingDirectory(WorkingDirectory), Consumer(Consumer), DepFS(std::move(DepFS)), Format(Format), OptimizeArgs(OptimizeArgs), - ModuleName(ModuleName) {} + DisableFree(DisableFree), ModuleName(ModuleName) {} bool runInvocation(std::shared_ptr Invocation, FileManager *FileMgr, @@ -149,6 +149,8 @@ DiagnosticConsumer *DiagConsumer) override { // Make a deep copy of the original Clang invocation. CompilerInvocation OriginalInvocation(*Invocation); + // Restore the value of DisableFree, which may be modified by Tooling. + OriginalInvocation.getFrontendOpts().DisableFree = DisableFree; // Create a compiler instance to handle the actual work. CompilerInstance ScanInstance(std::move(PCHContainerOps)); @@ -255,6 +257,7 @@ llvm::IntrusiveRefCntPtr DepFS; ScanningOutputFormat Format; bool OptimizeArgs; + bool DisableFree; llvm::Optional ModuleName; }; @@ -329,9 +332,13 @@ return runWithDiags(CreateAndPopulateDiagOpts(FinalCCommandLine).release(), [&](DiagnosticConsumer &DC, DiagnosticOptions &DiagOpts) { + // DisableFree is modified by Tooling for running + // in-process; preserve the original value, which is + // always true for a driver invocation. + bool DisableFree = true; DependencyScanningAction Action( WorkingDirectory, Consumer, DepFS, Format, - OptimizeArgs, ModuleName); + OptimizeArgs, DisableFree, ModuleName); // Create an invocation that uses the underlying file // system to ensure that any file system requests that // are made by the driver do not go through the diff --git a/clang/test/ClangScanDeps/modules-disable-free.c b/clang/test/ClangScanDeps/modules-disable-free.c new file mode 100644 --- /dev/null +++ b/clang/test/ClangScanDeps/modules-disable-free.c @@ -0,0 +1,34 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: sed -e "s|DIR|%/t|g" %t/compile-commands.json.in > %t/compile-commands.json + +// RUN: clang-scan-deps -compilation-database %t/compile-commands.json -j 1 -format experimental-full \ +// RUN: -mode preprocess-dependency-directives -generate-modules-path-args > %t/output +// RUN: FileCheck %s < %t/output + +// CHECK: "-disable-free", + +//--- compile-commands.json.in + +[{ + "directory": "DIR", + "command": "clang -c DIR/main.c -fmodules -fmodules-cache-path=DIR/module-cache -fimplicit-modules -fimplicit-module-maps", + "file": "DIR/main.c" +}] + +//--- module.modulemap + +module A { + header "a.h" +} + +//--- a.h + +void a(void); + +//--- main.c + +#include "a.h" +void m() { + a(); +}