https://github.com/MaggieYingYi updated https://github.com/llvm/llvm-project/pull/142409
>From c0cc666ab8864b665539a857dbdae6c592266227 Mon Sep 17 00:00:00 2001 From: Ying Yi <ying...@sony.com> Date: Mon, 2 Jun 2025 10:21:22 +0100 Subject: [PATCH] [Frontend][PCH]-Add support for ignoring PCH options (-ignore-pch). Visual Studio has an argument to ignore all PCH related switches. clang-cl has also support option /Y-. Having the same option in clang would be helpful. This commit is to add support for ignoring PCH options (-ignore-pch). --- clang/docs/PCHInternals.rst | 10 ++ clang/docs/UsersManual.rst | 14 +++ clang/include/clang/Driver/Options.td | 2 + clang/lib/Frontend/CompilerInvocation.cpp | 9 ++ clang/test/PCH/Inputs/ignored-pch.h | 6 ++ clang/test/PCH/ignored-pch.c | 114 ++++++++++++++++++++++ 6 files changed, 155 insertions(+) create mode 100644 clang/test/PCH/Inputs/ignored-pch.h create mode 100644 clang/test/PCH/ignored-pch.c diff --git a/clang/docs/PCHInternals.rst b/clang/docs/PCHInternals.rst index 079fba16711dc..de0b341460cac 100644 --- a/clang/docs/PCHInternals.rst +++ b/clang/docs/PCHInternals.rst @@ -31,6 +31,16 @@ option: $ clang -cc1 -include-pch test.h.pch test.c -o test.s +To ignore PCH options using ``clang -cc1``, use the option `-ignore-pch`: + +.. code-block:: bash + + $ clang -cc1 test.h -emit-pch -ignore-pch -o test.h.pch + $ clang -cc1 -include-pch test.h.pch -ignore-pch test.c -o test.s + +This option disables precompiled headers, overrides -emit-pch and -include-pch. +test.h.pch is not generated and not used as a prefix header. + Design Philosophy ----------------- diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index eb9a812f0c1c9..f12b6b4c02193 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -1458,6 +1458,20 @@ will be processed from the PCH file. Otherwise, Clang will report an error. ``test.h`` since ``test.h`` was included directly in the source file and not specified on the command line using ``-include-pch``. +Ignoring a PCH File +^^^^^^^^^^^^^^^^^^^ + +To ignore a PCH file using Clang, the `-Xclang -ignore-pch` option is passed to +``clang``: + +.. code-block:: console + + $ clang -x c-header test.h -Xclang -ignore-pch -o test.h.pch + $ clang -include-pch test.h.pch -Xclang -ignore-pch test.c -o test + +This option disables precompiled headers, overrides -emit-pch and -include-pch. +test.h.pch is not generated and not used as a prefix header. + Relocatable PCH Files ^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 5ca31c253ed8f..3ed87608bf592 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -8127,6 +8127,8 @@ def emit_header_unit : Flag<["-"], "emit-header-unit">, HelpText<"Generate C++20 header units from header files">; def emit_pch : Flag<["-"], "emit-pch">, HelpText<"Generate pre-compiled header file">; +def ignore_pch : Flag<["-"], "ignore-pch">, + HelpText<"Ignore pre-compiled header options">; def emit_llvm_only : Flag<["-"], "emit-llvm-only">, HelpText<"Build ASTs and convert to LLVM, discarding output">; def emit_codegen_only : Flag<["-"], "emit-codegen-only">, diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 2c02719121c73..19f81ff2fbe9d 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2982,6 +2982,15 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, #undef FRONTEND_OPTION_WITH_MARSHALLING Opts.ProgramAction = frontend::ParseSyntaxOnly; + + // If -ignore-pch is used, all pch handling is disabled. clang pch-related + // flags are removed. + if (Args.hasArg(options::OPT_ignore_pch)) { + Args.eraseArg(options::OPT_emit_pch); + Args.eraseArg(options::OPT_include_pch); + Args.eraseArg(options::OPT_ignore_pch); + } + if (const Arg *A = Args.getLastArg(OPT_Action_Group)) { OptSpecifier Opt = OptSpecifier(A->getOption().getID()); std::optional<frontend::ActionKind> ProgramAction = getFrontendAction(Opt); diff --git a/clang/test/PCH/Inputs/ignored-pch.h b/clang/test/PCH/Inputs/ignored-pch.h new file mode 100644 index 0000000000000..0956f9da1cb16 --- /dev/null +++ b/clang/test/PCH/Inputs/ignored-pch.h @@ -0,0 +1,6 @@ +#ifndef IGNORED_PCH_H +#define IGNORED_PCH_H +inline int f() { + return 42; +} +#endif // IGNORED_PCH_H \ No newline at end of file diff --git a/clang/test/PCH/ignored-pch.c b/clang/test/PCH/ignored-pch.c new file mode 100644 index 0000000000000..198ad0fde7d05 --- /dev/null +++ b/clang/test/PCH/ignored-pch.c @@ -0,0 +1,114 @@ +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang_cc1 -x c-header %S/Inputs/ignored-pch.h -emit-pch -o %t.pch +// RUN: %clang_cc1 %s -include-pch %t.pch -emit-llvm -o %t.ll +// RUN: ls %t.pch | FileCheck --check-prefix=CHECK-PCH %s +// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s + +// Check that -ignore-pch causes -emit-pch and -include-pch options to be ignored. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang_cc1 -x c-header %S/Inputs/ignored-pch.h -ignore-pch -emit-pch -o %t.pch +// RUN: %clang_cc1 %s -include-pch %t.pch -ignore-pch -emit-llvm -o %t.ll +// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s +// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s + +// Check that -ignore-pch is passed through Driver. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -Xclang -emit-pch -o %t.pch +// RUN: %clang -S %s -include-pch %t.pch -Xclang -emit-llvm -o %t.ll +// RUN: ls %t.pch | FileCheck --check-prefix=CHECK-PCH %s +// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s + +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -Xclang -ignore-pch -Xclang -emit-pch -o %t.pch +// RUN: %clang -S %s -include-pch %t.pch -Xclang -ignore-pch -Xclang -emit-llvm -o %t.ll +// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s +// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s + +// Check that -ignore-pch works for multiple PCH related options. +// Test with -building-pch-with-obj. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang_cc1 -x c-header %S/Inputs/ignored-pch.h -ignore-pch -emit-pch -building-pch-with-obj -o %t.pch +// RUN: %clang_cc1 %s -include-pch %t.pch -ignore-pch -emit-llvm -building-pch-with-obj -o %t.ll +// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s +// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s + +// Test with -fallow-pch-with-compiler-errors. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang_cc1 -x c-header %S/Inputs/ignored-pch.h -ignore-pch -emit-pch -fallow-pch-with-compiler-errors -o %t.pch +// RUN: %clang_cc1 %s -include-pch %t.pch -ignore-pch -emit-llvm -fallow-pch-with-compiler-errors -o %t.ll +// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s +// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s + +// Test with -fallow-pch-with-different-modules-cache-path. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang_cc1 -x c-header %S/Inputs/ignored-pch.h -emit-pch -fallow-pch-with-different-modules-cache-path -o %t.pch +// RUN: %clang_cc1 %s -include-pch %t.pch -emit-llvm -fallow-pch-with-different-modules-cache-path -o %t.ll +// RUN: ls %t.pch | FileCheck --check-prefix=CHECK-PCH %s +// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s + +// Test with -fpch-codegen. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang_cc1 -x c-header %S/Inputs/ignored-pch.h -emit-pch -fpch-codegen -o %t.pch +// RUN: %clang_cc1 %s -include-pch %t.pch -emit-llvm -fpch-codegen -o %t.ll +// RUN: ls %t.pch | FileCheck --check-prefix=CHECK-PCH %s +// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s + +// Test with -fpch-debuginfo. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang_cc1 -x c-header %S/Inputs/ignored-pch.h -emit-pch -fpch-debuginfo -o %t.pch +// RUN: %clang_cc1 %s -include-pch %t.pch -emit-llvm -fpch-debuginfo -o %t.ll +// RUN: ls %t.pch | FileCheck --check-prefix=CHECK-PCH %s +// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s + +// Test with -fpch-instantiate-templates. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang_cc1 -x c-header %S/Inputs/ignored-pch.h -emit-pch -fpch-instantiate-templates -o %t.pch +// RUN: %clang_cc1 %s -include-pch %t.pch -emit-llvm -fpch-instantiate-templates -o %t.ll +// RUN: ls %t.pch | FileCheck --check-prefix=CHECK-PCH %s +// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s + +// Test with -fno-pch-timestamp. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang_cc1 -x c-header %S/Inputs/ignored-pch.h -emit-pch -fno-pch-timestamp -o %t.pch +// RUN: %clang_cc1 %s -include-pch %t.pch -emit-llvm -fno-pch-timestamp -o %t.ll +// RUN: ls %t.pch | FileCheck --check-prefix=CHECK-PCH %s +// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s + +// Test with -fno-validate-pch. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang_cc1 -x c-header %S/Inputs/ignored-pch.h -emit-pch -fno-validate-pch -o %t.pch +// RUN: %clang_cc1 %s -include-pch %t.pch -emit-llvm -fno-validate-pch -o %t.ll +// RUN: ls %t.pch | FileCheck --check-prefix=CHECK-PCH %s +// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s + +// Test with -relocatable-pch. +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang_cc1 -x c-header %S/Inputs/ignored-pch.h -emit-pch -relocatable-pch -o %t.pch +// RUN: %clang_cc1 %s -include-pch %t.pch -emit-llvm -relocatable-pch -o %t.ll +// RUN: ls %t.pch | FileCheck --check-prefix=CHECK-PCH %s +// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s + +// Test with -pch-through-hdrstop-create/-pch-through-hdrstop-use +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang_cc1 -x c-header %S/Inputs/ignored-pch.h -emit-pch -pch-through-hdrstop-create -o %t.pch +// RUN: %clang_cc1 %s -include-pch %t.pch -emit-llvm -pch-through-hdrstop-use -o %t.ll +// RUN: ls %t.pch | FileCheck --check-prefix=CHECK-PCH %s +// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s + +// Test with AST dump output: +// RUN: rm -rf %t.pch %t.ll +// RUN: %clang_cc1 -x c-header %S/Inputs/ignored-pch.h -emit-pch -o %t.pch +// RUN: %clang_cc1 %s -include-pch %t.pch -ast-dump-all | FileCheck --check-prefix=CHECK-AST-PCH %s +// RUN: %clang_cc1 %s -include-pch %t.pch -ignore-pch -ast-dump-all | FileCheck --check-prefix=CHECK-AST %s + +// CHECK-PCH: ignored-pch.c.{{.*}}.pch +// CHECK-OBJ: ignored-pch.c.{{.*}}.ll +// CHECK-ERROR: ignored-pch.c.{{.*}}.pch{{'?}}: No such file or directory +// CHECK-AST-PCH: <undeserialized declarations> +// CHECK-AST-NOT: <undeserialized declarations> + +#include "Inputs/ignored-pch.h" +#pragma hdrstop +int main() { + return f(); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits