diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h +++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h @@ -46,9 +46,10 @@ /// mismatching size of the file. If file is not minimized, the full file is /// read and copied into memory to ensure that it's not memory mapped to avoid /// running out of file descriptors. - static CachedFileSystemEntry createFileEntry(StringRef Filename, - llvm::vfs::FileSystem &FS, - bool Minimize = true); + static CachedFileSystemEntry + createFileEntry(StringRef Filename, llvm::vfs::FileSystem &FS, + bool Minimize = true, + bool PadMinimizedToOriginalSize = false); /// Create an entry that represents a directory on the filesystem. static CachedFileSystemEntry createDirectoryEntry(llvm::vfs::Status &&Stat); @@ -156,6 +157,9 @@ /// The set of files that should not be minimized. llvm::StringSet<> IgnoredFiles; + /// Whether to pad minimized files to the original size. + bool PadMinimizedToOriginalSize = false; + private: void setCachedEntry(StringRef Filename, const CachedFileSystemEntry *Entry) { bool IsInserted = Cache.try_emplace(Filename, Entry).second; diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp @@ -15,8 +15,10 @@ using namespace tooling; using namespace dependencies; -CachedFileSystemEntry CachedFileSystemEntry::createFileEntry( - StringRef Filename, llvm::vfs::FileSystem &FS, bool Minimize) { +CachedFileSystemEntry +CachedFileSystemEntry::createFileEntry(StringRef Filename, + llvm::vfs::FileSystem &FS, bool Minimize, + bool PadMinimizedToOriginalSize) { // Load the file and its content from the file system. llvm::ErrorOr> MaybeFile = FS.openFileForRead(Filename); @@ -37,7 +39,8 @@ const auto &Buffer = *MaybeBuffer; SmallVector Tokens; if (!Minimize || minimizeSourceToDependencyDirectives( - Buffer->getBuffer(), MinimizedFileContents, Tokens)) { + Buffer->getBuffer(), MinimizedFileContents, Tokens, + nullptr, SourceLocation(), PadMinimizedToOriginalSize)) { // Use the original file unless requested otherwise, or // if the minimization failed. // FIXME: Propage the diagnostic if desired by the client. @@ -185,7 +188,7 @@ std::move(*MaybeStatus)); else CacheEntry = CachedFileSystemEntry::createFileEntry( - Filename, FS, !KeepOriginalSource); + Filename, FS, !KeepOriginalSource, PadMinimizedToOriginalSize); } Result = &CacheEntry; 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 @@ -139,6 +139,15 @@ FileMgr->setVirtualFileSystem(createVFSFromCompilerInvocation( CI, Compiler.getDiagnostics(), DepFS)); + // If we are about to import a PCH, make sure minimized files are padded + // to sizes of the originals. The PCH might have been built from + // non-minimized files and any disagreement on the file size causes issues + // in the implicit build. + // TODO: Consider padding only files that contributed to the PCH and its + // modules. + DepFS->PadMinimizedToOriginalSize = + !Compiler.getPreprocessorOpts().ImplicitPCHInclude.empty(); + // Pass the skip mappings which should speed up excluded conditional block // skipping in the preprocessor. if (PPSkipMappings) diff --git a/clang/test/ClangScanDeps/modules-pch.c b/clang/test/ClangScanDeps/modules-pch.c --- a/clang/test/ClangScanDeps/modules-pch.c +++ b/clang/test/ClangScanDeps/modules-pch.c @@ -6,7 +6,7 @@ // RUN: sed "s|DIR|%/t|g" %S/Inputs/modules-pch/cdb_pch.json > %t/cdb.json // RUN: echo -%t > %t/result_pch.json // RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-full \ -// RUN: -generate-modules-path-args -module-files-dir %t/build -mode preprocess >> %t/result_pch.json +// RUN: -generate-modules-path-args -module-files-dir %t/build >> %t/result_pch.json // RUN: cat %t/result_pch.json | sed 's:\\\\\?:/:g' | FileCheck %s -check-prefix=CHECK-PCH // // Check we didn't build the PCH during dependency scanning. @@ -127,9 +127,8 @@ // // RUN: sed "s|DIR|%/t|g" %S/Inputs/modules-pch/cdb_tu.json > %t/cdb.json // RUN: echo -%t > %t/result_tu.json -// FIXME: Make this work with '-mode preprocess-minimized-sources'. // RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-full \ -// RUN: -generate-modules-path-args -module-files-dir %t/build -mode preprocess >> %t/result_tu.json +// RUN: -generate-modules-path-args -module-files-dir %t/build >> %t/result_tu.json // RUN: cat %t/result_tu.json | sed 's:\\\\\?:/:g' | FileCheck %s -check-prefix=CHECK-TU // // CHECK-TU: -[[PREFIX:.*]] @@ -193,7 +192,7 @@ // RUN: sed "s|DIR|%/t|g" %S/Inputs/modules-pch/cdb_tu_with_common.json > %t/cdb.json // RUN: echo -%t > %t/result_tu_with_common.json // RUN: clang-scan-deps -compilation-database %t/cdb.json -format experimental-full \ -// RUN: -generate-modules-path-args -module-files-dir %t/build -mode preprocess >> %t/result_tu_with_common.json +// RUN: -generate-modules-path-args -module-files-dir %t/build >> %t/result_tu_with_common.json // RUN: cat %t/result_tu_with_common.json | sed 's:\\\\\?:/:g' | FileCheck %s -check-prefix=CHECK-TU-WITH-COMMON // // CHECK-TU-WITH-COMMON: -[[PREFIX:.*]]