diff --git a/clang/lib/Driver/Job.cpp b/clang/lib/Driver/Job.cpp index 68bb4ab102ee..9fd8808af302 100644 --- a/clang/lib/Driver/Job.cpp +++ b/clang/lib/Driver/Job.cpp @@ -50,9 +50,8 @@ static bool skipArgs(const char *Flag, bool HaveCrashVFS, int &SkipNum, bool ShouldSkip = llvm::StringSwitch(Flag) .Cases("-MF", "-MT", "-MQ", "-serialize-diagnostic-file", true) .Cases("-o", "-coverage-file", "-dependency-file", true) - .Cases("-fdebug-compilation-dir", "-include-pch", true) + .Cases("-fdebug-compilation-dir", "-diagnostic-log-file", true) .Cases("-dwarf-debug-flags", "-ivfsoverlay", true) - .Case("-diagnostic-log-file", true) .Default(false); if (ShouldSkip) return true; @@ -64,7 +63,7 @@ static bool skipArgs(const char *Flag, bool HaveCrashVFS, int &SkipNum, .Cases("-internal-externc-isystem", "-iprefix", true) .Cases("-iwithprefixbefore", "-isystem", "-iquote", true) .Cases("-isysroot", "-I", "-F", "-resource-dir", true) - .Case("-iframework", true) + .Cases("-iframework", "-include-pch", true) .Default(false); if (IsInclude) return HaveCrashVFS ? false : true; diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index cd67166d518f..5c78f8100e5b 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -149,6 +149,38 @@ static void collectHeaderMaps(const HeaderSearch &HS, MDC->addFile(Name); } +static void collectIncludePCH(CompilerInstance &CI, + std::shared_ptr MDC) { + const PreprocessorOptions &PPOpts = CI.getPreprocessorOpts(); + if (PPOpts.ImplicitPCHInclude.empty()) + return; + + StringRef PCHInclude = PPOpts.ImplicitPCHInclude; + FileManager &FileMgr = CI.getFileManager(); + const DirectoryEntry *PCHDir = FileMgr.getDirectory(PCHInclude); + if (!PCHDir) { + MDC->addFile(PCHInclude); + return; + } + + std::error_code EC; + SmallString<128> DirNative; + llvm::sys::path::native(PCHDir->getName(), DirNative); + vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem(); + SimpleASTReaderListener Validator(CI.getPreprocessor()); + for (vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd; + Dir != DirEnd && !EC; Dir.increment(EC)) { + // Check whether this is an AST file. ASTReader::isAcceptableASTFile is not + // used here since we're not interested in validating the PCH at this time, + // but only to check whether this is a file containing an AST. + if (!ASTReader::readASTFileControlBlock( + Dir->getName(), FileMgr, CI.getPCHContainerReader(), + /*FindModuleFileExtensions=*/false, Validator, + /*ValidateDiagnosticOptions=*/false)) + MDC->addFile(Dir->getName()); + } +} + // Diagnostics static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts, const CodeGenOptions *CodeGenOpts, @@ -379,6 +411,7 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) { if (ModuleDepCollector) { addDependencyCollector(ModuleDepCollector); collectHeaderMaps(PP->getHeaderSearchInfo(), ModuleDepCollector); + collectIncludePCH(*this, ModuleDepCollector); } for (auto &Listener : DependencyCollectors) diff --git a/clang/test/Modules/crash-vfs-include-pch.m b/clang/test/Modules/crash-vfs-include-pch.m new file mode 100644 index 000000000000..78a8e149a41b --- /dev/null +++ b/clang/test/Modules/crash-vfs-include-pch.m @@ -0,0 +1,43 @@ +// REQUIRES: crash-recovery, shell, system-darwin +// +// RUN: rm -rf %t +// RUN: mkdir -p %t/m %t/out + +// RUN: %clang_cc1 -x objective-c-header -emit-pch %S/Inputs/pch-used.h \ +// RUN: -o %t/out/pch-used.h.pch -fmodules -fimplicit-module-maps \ +// RUN: -fmodules-cache-path=%t/cache -O0 \ +// RUN: -isystem %S/Inputs/System/usr/include + +// RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \ +// RUN: %clang %s -E -include-pch %t/out/pch-used.h.pch -fmodules -nostdlibinc \ +// RUN: -fimplicit-module-maps -fmodules-cache-path=%t/cache -O0 \ +// RUN: -Xclang -fno-validate-pch -isystem %S/Inputs/System/usr/include \ +// RUN: -o %t/output.E 2>&1 | FileCheck %s + +// RUN: FileCheck --check-prefix=CHECKSH %s -input-file %t/crash-vfs-*.sh +// RUN: FileCheck --check-prefix=CHECKYAML %s -input-file \ +// RUN: %t/crash-vfs-*.cache/vfs/vfs.yaml + +void f() { SPXTrace(); } +void g() { double x = DBL_MAX; } + +// CHECK: Preprocessed source(s) and associated run script(s) are located at: +// CHECK-NEXT: note: diagnostic msg: {{.*}}.m +// CHECK-NEXT: note: diagnostic msg: {{.*}}.cache + +// CHECKSH: "-include-pch" "/[[INCPATH:.*]]/out/pch-used.h.pch" +// CHECKSH: "crash-vfs-{{[^ ]*}}.m" +// CHECKSH: "-ivfsoverlay" "crash-vfs-{{[^ ]*}}.cache/vfs/vfs.yaml" +// CHECKSH: "-fmodules-cache-path=crash-vfs-{{[^ ]*}}.cache/repro-modules" + +// CHECKYAML: 'case-sensitive': +// CHECKYAML-NEXT: 'use-external-names': 'false', +// CHECKYAML-NEXT: 'overlay-relative': 'true', +// CHECKYAML-NEXT: 'ignore-non-existent-contents': 'false' +// CHECKYAML: 'type': 'directory' +// CHECKYAML: 'name': "/[[PATH:.*]]/out", +// CHECKYAML-NEXT: 'contents': [ +// CHECKYAML-NEXT: { +// CHECKYAML-NEXT: 'type': 'file', +// CHECKYAML-NEXT: 'name': "pch-used.h.pch", +// CHECKYAML-NEXT: 'external-contents': "/[[PATH]]/out/pch-used.h.pch"