From ce539b54e365e237bd33a85d97e72a228d7624ae Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Wed, 29 Mar 2017 17:33:09 +0000 Subject: [PATCH] [PCH] Attach instance's dependency collectors to PCH external AST sources. Summary: When a PCH is included via -include-pch, clang should treat the current TU as dependent on the sourcefile that the PCH was generated from. This is currently _partly_ accomplished by InitializePreprocessor calling AddImplicitIncludePCH to synthesize an implicit #include of the sourcefile, into the preprocessor's Predefines buffer. For FrontendActions such as PreprocessOnlyAction (which is, curiously, what the driver winds up running one of in response to a plain clang -M) this is sufficient: the preprocessor cranks over its Predefines and emits a dependency reference to the initial sourcefile. For other FrontendActions (for example -emit-obj or -fsyntax-only) the Predefines buffer is reset to the suggested predefines buffer from the PCH, so the dependency edge is lost. The result is that clang emits a .d file in those cases that lacks a reference to the .h file responsible for the input (and in Swift's case, our .swiftdeps file winds up not including a reference to the source file for a PCH bridging header.) This patch fixes the problem by taking a different tack: ignoring the Predefines buffer (which seems a bit like a hack anyways) and directly attaching the CompilerInstance's DependencyCollectors (and legacy DependencyFileGenerator) to the ASTReader for the external AST. This approach is similar to the one chosen in earlier consultation with Bruno and Ben, and I think it's the least-bad solution, given several options. Reviewers: bruno, benlangmuir, doug.gregor Reviewed By: bruno, doug.gregor Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D31378 llvm-svn: 299009 --- clang/include/clang/Frontend/CompilerInstance.h | 2 ++ clang/lib/Frontend/CompilerInstance.cpp | 10 ++++++++++ clang/test/PCH/emit-dependencies.c | 9 +++++++++ 3 files changed, 21 insertions(+) create mode 100644 clang/test/PCH/emit-dependencies.c diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h index bdcec54..4f7149f 100644 --- a/clang/include/clang/Frontend/CompilerInstance.h +++ b/clang/include/clang/Frontend/CompilerInstance.h @@ -662,6 +662,8 @@ public: bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, const PCHContainerReader &PCHContainerRdr, ArrayRef> Extensions, + DependencyFileGenerator *DependencyFile, + ArrayRef> DependencyCollectors, void *DeserializationListener, bool OwnDeserializationListener, bool Preamble, bool UseGlobalModuleIndex); diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index f660429..8b4b169 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -497,6 +497,8 @@ void CompilerInstance::createPCHExternalASTSource( AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(), getPCHContainerReader(), getFrontendOpts().ModuleFileExtensions, + TheDependencyFileGenerator.get(), + DependencyCollectors, DeserializationListener, OwnDeserializationListener, Preamble, getFrontendOpts().UseGlobalModuleIndex); @@ -507,6 +509,8 @@ IntrusiveRefCntPtr CompilerInstance::createPCHExternalASTSource( bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, const PCHContainerReader &PCHContainerRdr, ArrayRef> Extensions, + DependencyFileGenerator *DependencyFile, + ArrayRef> DependencyCollectors, void *DeserializationListener, bool OwnDeserializationListener, bool Preamble, bool UseGlobalModuleIndex) { HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts(); @@ -524,6 +528,12 @@ IntrusiveRefCntPtr CompilerInstance::createPCHExternalASTSource( Reader->setDeserializationListener( static_cast(DeserializationListener), /*TakeOwnership=*/OwnDeserializationListener); + + if (DependencyFile) + DependencyFile->AttachToASTReader(*Reader); + for (auto &Listener : DependencyCollectors) + Listener->attachToASTReader(*Reader); + switch (Reader->ReadAST(Path, Preamble ? serialization::MK_Preamble : serialization::MK_PCH, diff --git a/clang/test/PCH/emit-dependencies.c b/clang/test/PCH/emit-dependencies.c new file mode 100644 index 0000000..c719b9e --- /dev/null +++ b/clang/test/PCH/emit-dependencies.c @@ -0,0 +1,9 @@ +// RUN: rm -f %t.pch +// RUN: %clang_cc1 -emit-pch -o %t.pch %S/Inputs/chain-decls1.h +// RUN: %clang_cc1 -include-pch %t.pch -fsyntax-only -MT %s.o -dependency-file - %s | FileCheck %s +// CHECK: Inputs/chain-decls1.h + +int main() { + f(); + return 0; +} -- 2.7.4