[clang] [Frontend][PCH]-Add support for ignoring PCH options (-ignore-pch). (PR #142409)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 2 07:52:06 PDT 2025
https://github.com/MaggieYingYi created https://github.com/llvm/llvm-project/pull/142409
As part of the mixed host bring up, the support of PCH (precompiled headers) has been raised as a potential issue. 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).
>From 6eb6900243f4561d071656d39dcaa4759b074d34 Mon Sep 17 00:00:00 2001
From: Ying Yi <ying.yi at sony.com>
Date: Mon, 2 Jun 2025 10:21:22 +0100
Subject: [PATCH] [Frontend][PCH]-Add support for ignoring PCH options
(-ignore-pch).
As part of the mixed host bring up, the support of PCH (precompiled headers) has been raised as a potential issue. 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();
+}
More information about the cfe-commits
mailing list