jansvoboda11 created this revision. jansvoboda11 added reviewers: Bigcheese, dexonsmith, arphaman. jansvoboda11 requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
The `PreprocessOnlyAction` doesn't support loading the AST file of a precompiled header. This is problematic for dependency scanning, since the `#include` manufactured for the PCH is treated as textual. This means the PCH contents get scanned with each TU, which is redundant. Moreover, dependencies of the PCH end up being considered dependency of the TU. To handle AST file of PCH properly, this patch creates new `FrontendAction` that behaves the same way `PreprocessorOnlyAction` does, but treats the manufactured PCH `#include` as a normal compilation would (by not claiming it only uses a preprocessor and creating the default AST consumer). The AST file is now reported as a file dependency of the TU. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D103524 Files: clang/include/clang/Frontend/FrontendActions.h clang/lib/Frontend/FrontendActions.cpp clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp clang/test/ClangScanDeps/modules-pch.c
Index: clang/test/ClangScanDeps/modules-pch.c =================================================================== --- clang/test/ClangScanDeps/modules-pch.c +++ clang/test/ClangScanDeps/modules-pch.c @@ -4,10 +4,56 @@ // Explicitly build the PCH: // // RUN: %clang -x c-header %t/pch.h -fmodules -gmodules -fimplicit-module-maps \ -// RUN: -fmodules-cache-path=%t/cache -o %t/pch.h.gch +// RUN: -fmodules-cache-path=%t/cache -o %t/pch.h.gch -fno-implicit-modules -fno-implicit-module-maps // Scan dependencies of the TU: // // RUN: sed "s|DIR|%/t|g" %S/Inputs/modules-pch/cdb_tu.json > %t/cdb_tu.json +// RUN: echo -%t > %t/result_tu.json // RUN: clang-scan-deps -compilation-database %t/cdb_tu.json -format experimental-full \ -// RUN: -generate-modules-path-args -build-dir %t/build +// RUN: -generate-modules-path-args -build-dir %t/build -mode preprocess >> %t/result_tu.json +// RUN: cat %t/result_tu.json | FileCheck %s -check-prefix=CHECK-TU +// +// CHECK-TU: -[[PREFIX:.*]] +// CHECK-TU-NEXT: { +// CHECK-TU-NEXT: "modules": [ +// CHECK-TU-NEXT: { +// CHECK-TU-NEXT: "clang-module-deps": [], +// CHECK-TU-NEXT: "clang-modulemap-file": "[[PREFIX]]/module.modulemap", +// CHECK-TU-NEXT: "command-line": [ +// CHECK-TU-NEXT: "-cc1", +// CHECK-TU: "-emit-module", +// CHECK-TU: "-fmodule-name=ModTU", +// CHECK-TU: "-fno-implicit-modules", +// CHECK-TU: ], +// CHECK-TU-NEXT: "context-hash": "[[HASH_MOD_TU:.*]]", +// CHECK-TU-NEXT: "file-deps": [ +// CHECK-TU-NEXT: "[[PREFIX]]/mod_tu.h", +// CHECK-TU-NEXT: "[[PREFIX]]/module.modulemap" +// CHECK-TU-NEXT: ], +// CHECK-TU-NEXT: "name": "ModTU" +// CHECK-TU-NEXT: } +// CHECK-TU-NEXT: ], +// CHECK-TU-NEXT: "translation-units": [ +// CHECK-TU-NEXT: { +// CHECK-TU-NEXT: "clang-context-hash": "[[HASH_TU:.*]]", +// CHECK-TU-NEXT: "clang-module-deps": [ +// CHECK-TU-NEXT: { +// CHECK-TU-NEXT: "context-hash": "[[HASH_MOD_TU]]", +// CHECK-TU-NEXT: "module-name": "ModTU" +// CHECK-TU-NEXT: } +// CHECK-TU-NEXT: ], +// CHECK-TU-NEXT: "command-line": [ +// CHECK-TU-NEXT: "-fno-implicit-modules", +// CHECK-TU-NEXT: "-fno-implicit-module-maps", +// CHECK-TU-NEXT: "-fmodule-file=[[PREFIX]]/build/[[HASH_MOD_TU]]/ModTU-{{.*}}.pcm", +// CHECK-TU-NEXT: "-fmodule-map-file=[[PREFIX]]/module.modulemap" +// CHECK-TU-NEXT: ], +// CHECK-TU-NEXT: "file-deps": [ +// CHECK-TU-NEXT: "[[PREFIX]]/tu.c", +// CHECK-TU-NEXT: "[[PREFIX]]/pch.h.gch" +// CHECK-TU-NEXT: ], +// CHECK-TU-NEXT: "input-file": "[[PREFIX]]/tu.c" +// CHECK-TU-NEXT: } +// CHECK-TU-NEXT: ] +// CHECK-TU-NEXT: } Index: clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp =================================================================== --- clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -156,6 +156,9 @@ MDC.MainFile = std::string( Instance.getSourceManager().getFileEntryForID(MainFileID)->getName()); + if (!Instance.getPreprocessorOpts().ImplicitPCHInclude.empty()) + MDC.FileDeps.push_back(Instance.getPreprocessorOpts().ImplicitPCHInclude); + for (const Module *M : DirectModularDeps) handleTopLevelModule(M); Index: clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp =================================================================== --- clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -133,7 +133,7 @@ // the impact of strict context hashing. Compiler.getHeaderSearchOpts().ModulesStrictContextHash = true; - auto Action = std::make_unique<PreprocessOnlyAction>(); + auto Action = std::make_unique<ReadPCHAndPreprocessAction>(); const bool Result = Compiler.ExecuteAction(*Action); if (!DepFS) FileMgr->clearStatCache(); Index: clang/lib/Frontend/FrontendActions.cpp =================================================================== --- clang/lib/Frontend/FrontendActions.cpp +++ clang/lib/Frontend/FrontendActions.cpp @@ -62,6 +62,27 @@ void InitOnlyAction::ExecuteAction() { } +// Basically PreprocessOnlyAction::ExecuteAction. +void ReadPCHAndPreprocessAction::ExecuteAction() { + Preprocessor &PP = getCompilerInstance().getPreprocessor(); + + // Ignore unknown pragmas. + PP.IgnorePragmas(); + + Token Tok; + // Start parsing the specified input file. + PP.EnterMainSourceFile(); + do { + PP.Lex(Tok); + } while (Tok.isNot(tok::eof)); +} + +std::unique_ptr<ASTConsumer> +ReadPCHAndPreprocessAction::CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) { + return std::make_unique<ASTConsumer>(); +} + //===----------------------------------------------------------------------===// // AST Consumer Actions //===----------------------------------------------------------------------===// Index: clang/include/clang/Frontend/FrontendActions.h =================================================================== --- clang/include/clang/Frontend/FrontendActions.h +++ clang/include/clang/Frontend/FrontendActions.h @@ -34,6 +34,17 @@ bool usesPreprocessorOnly() const override { return false; } }; +/// Preprocessor-based frontend action that also loads PCH files. +class ReadPCHAndPreprocessAction : public FrontendAction { + void ExecuteAction() override; + + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; + +public: + bool usesPreprocessorOnly() const override { return false; } +}; + class DumpCompilerOptionsAction : public FrontendAction { std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits