forked from OSchip/llvm-project
[CrashReproducer] Collect PCH included via -include-pch
Collect the necessary input PCH files. Do not try to validate the AST before copying it out because if the crash is in this path, we won't be able to collect it. Instead only check if it's a file containg an AST. rdar://problem/27913709 llvm-svn: 289460
This commit is contained in:
parent
b4d56f1a4f
commit
7aff2bb3d2
|
@ -50,9 +50,8 @@ static bool skipArgs(const char *Flag, bool HaveCrashVFS, int &SkipNum,
|
||||||
bool ShouldSkip = llvm::StringSwitch<bool>(Flag)
|
bool ShouldSkip = llvm::StringSwitch<bool>(Flag)
|
||||||
.Cases("-MF", "-MT", "-MQ", "-serialize-diagnostic-file", true)
|
.Cases("-MF", "-MT", "-MQ", "-serialize-diagnostic-file", true)
|
||||||
.Cases("-o", "-coverage-file", "-dependency-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)
|
.Cases("-dwarf-debug-flags", "-ivfsoverlay", true)
|
||||||
.Case("-diagnostic-log-file", true)
|
|
||||||
.Default(false);
|
.Default(false);
|
||||||
if (ShouldSkip)
|
if (ShouldSkip)
|
||||||
return true;
|
return true;
|
||||||
|
@ -64,7 +63,7 @@ static bool skipArgs(const char *Flag, bool HaveCrashVFS, int &SkipNum,
|
||||||
.Cases("-internal-externc-isystem", "-iprefix", true)
|
.Cases("-internal-externc-isystem", "-iprefix", true)
|
||||||
.Cases("-iwithprefixbefore", "-isystem", "-iquote", true)
|
.Cases("-iwithprefixbefore", "-isystem", "-iquote", true)
|
||||||
.Cases("-isysroot", "-I", "-F", "-resource-dir", true)
|
.Cases("-isysroot", "-I", "-F", "-resource-dir", true)
|
||||||
.Case("-iframework", true)
|
.Cases("-iframework", "-include-pch", true)
|
||||||
.Default(false);
|
.Default(false);
|
||||||
if (IsInclude)
|
if (IsInclude)
|
||||||
return HaveCrashVFS ? false : true;
|
return HaveCrashVFS ? false : true;
|
||||||
|
|
|
@ -149,6 +149,38 @@ static void collectHeaderMaps(const HeaderSearch &HS,
|
||||||
MDC->addFile(Name);
|
MDC->addFile(Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void collectIncludePCH(CompilerInstance &CI,
|
||||||
|
std::shared_ptr<ModuleDependencyCollector> 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
|
// Diagnostics
|
||||||
static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts,
|
static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts,
|
||||||
const CodeGenOptions *CodeGenOpts,
|
const CodeGenOptions *CodeGenOpts,
|
||||||
|
@ -379,6 +411,7 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
|
||||||
if (ModuleDepCollector) {
|
if (ModuleDepCollector) {
|
||||||
addDependencyCollector(ModuleDepCollector);
|
addDependencyCollector(ModuleDepCollector);
|
||||||
collectHeaderMaps(PP->getHeaderSearchInfo(), ModuleDepCollector);
|
collectHeaderMaps(PP->getHeaderSearchInfo(), ModuleDepCollector);
|
||||||
|
collectIncludePCH(*this, ModuleDepCollector);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &Listener : DependencyCollectors)
|
for (auto &Listener : DependencyCollectors)
|
||||||
|
|
|
@ -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"
|
Loading…
Reference in New Issue