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 1/6] [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(); +} >From 71ad57b6e9497ee69fd42735b385bbca06aeede1 Mon Sep 17 00:00:00 2001 From: Ying Yi <ying...@sony.com> Date: Mon, 2 Jun 2025 17:48:37 +0100 Subject: [PATCH 2/6] Inserting a new line in the test input file. --- clang/test/PCH/Inputs/ignored-pch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/PCH/Inputs/ignored-pch.h b/clang/test/PCH/Inputs/ignored-pch.h index 0956f9da1cb16..56047037c331f 100644 --- a/clang/test/PCH/Inputs/ignored-pch.h +++ b/clang/test/PCH/Inputs/ignored-pch.h @@ -3,4 +3,4 @@ inline int f() { return 42; } -#endif // IGNORED_PCH_H \ No newline at end of file +#endif // IGNORED_PCH_H >From a3da3bc79589919840c93f4ccc0201a1b9027fb3 Mon Sep 17 00:00:00 2001 From: Ying Yi <ying...@sony.com> Date: Tue, 3 Jun 2025 11:29:13 +0100 Subject: [PATCH 3/6] Fix an error of unexpected indentation. --- clang/include/clang/Basic/DiagnosticGroups.td | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index be75b9ee6e3f6..beda73e675fc6 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -813,19 +813,19 @@ changes to one object won't affect the others, the object's initializer will run once per copy, etc. Specifically, this warning fires when it detects an object which: - 1. Is defined as ``inline`` in a header file (so it might get compiled into multiple libaries), and - 2. Has external linkage (otherwise it's supposed to be duplicated), and - 3. Has hidden visibility. +1. Is defined as ``inline`` in a header file (so it might get compiled into multiple libaries), and +2. Has external linkage (otherwise it's supposed to be duplicated), and +3. Has hidden visibility. As well as one of the following: - 1. The object is mutable, or - 2. The object's initializer definitely has side effects. +1. The object is mutable, or +2. The object's initializer definitely has side effects. The warning can be resolved by removing one of the conditions above. In rough order of preference, this may be done by: - 1. Marking the object ``const`` (if possible) - 2. Moving the object's definition to a source file - 3. Giving the object non-hidden visibility, e.g. using ``__attribute((visibility("default")))``. +1. Marking the object ``const`` (if possible) +2. Moving the object's definition to a source file +3. Giving the object non-hidden visibility, e.g. using ``__attribute((visibility("default")))``. Note that for (2), all levels of a pointer variable must be constant; ``const int*`` will trigger the warning because the pointer itself is mutable. >From 9e6e7e741b56d81807cf07f53e8e94e0ce3f56cb Mon Sep 17 00:00:00 2001 From: Ying Yi <ying...@sony.com> Date: Wed, 4 Jun 2025 23:39:22 +0100 Subject: [PATCH 4/6] Update the patch following reviewer's comment: 1. Implement -ignore-pch as a Driver and CC1 option. 2. Add a Driver test. 3. Update documents. --- clang/docs/PCHInternals.rst | 2 +- clang/docs/UsersManual.rst | 3 +- clang/include/clang/Driver/Options.td | 5 +- clang/lib/Driver/Driver.cpp | 10 +++ clang/lib/Driver/ToolChains/Clang.cpp | 5 +- clang/lib/Frontend/CompilerInvocation.cpp | 8 -- clang/test/Driver/ignored-pch.cpp | 19 +++++ clang/test/PCH/ignored-pch.c | 99 +++++++++++------------ 8 files changed, 86 insertions(+), 65 deletions(-) create mode 100644 clang/test/Driver/ignored-pch.cpp diff --git a/clang/docs/PCHInternals.rst b/clang/docs/PCHInternals.rst index de0b341460cac..f724229102729 100644 --- a/clang/docs/PCHInternals.rst +++ b/clang/docs/PCHInternals.rst @@ -31,7 +31,7 @@ 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`: +To ignore PCH options, use the option `-ignore-pch`: .. code-block:: bash diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index f12b6b4c02193..d325024c759ff 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -1461,8 +1461,7 @@ will be processed from the PCH file. Otherwise, Clang will report an error. Ignoring a PCH File ^^^^^^^^^^^^^^^^^^^ -To ignore a PCH file using Clang, the `-Xclang -ignore-pch` option is passed to -``clang``: +To ignore PCH options, a `-ignore-pch` option is passed to ``clang``: .. code-block:: console diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 3ed87608bf592..dcea81b0099ae 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3348,6 +3348,9 @@ defm pch_codegen: OptInCC1FFlag<"pch-codegen", "Generate ", "Do not generate ", "code for uses of this PCH that assumes an explicit object file will be built for the PCH">; defm pch_debuginfo: OptInCC1FFlag<"pch-debuginfo", "Generate ", "Do not generate ", "debug info for types in an object file built from this PCH and do not generate them elsewhere">; +def ignore_pch : Flag<["-"], "ignore-pch">, Group<f_Group>, + Visibility<[ClangOption, CC1Option]>, + HelpText<"Disable precompiled headers, overrides -emit-pch and -include-pch">; def fimplicit_module_maps : Flag <["-"], "fimplicit-module-maps">, Group<f_Group>, Visibility<[ClangOption, CC1Option, CLOption]>, @@ -8127,8 +8130,6 @@ 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/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 87c827de17d9e..34f6cd4a3cd4b 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -4286,6 +4286,16 @@ void Driver::handleArguments(Compilation &C, DerivedArgList &Args, YcArg = YuArg = nullptr; } + Arg *IncludePCHArg = Args.getLastArg(options::OPT_include_pch); + if (IncludePCHArg && (FinalPhase == phases::Preprocess || + Args.hasArg(options::OPT_ignore_pch))) { + // If only preprocessing or -ignore-pch is used, -include-pch is disabled. + // Since -emit-pch is CC1option, it will not be added to command argments if + // -ignore-pch is used. + Args.eraseArg(options::OPT_include_pch); + IncludePCHArg = nullptr; + } + bool LinkOnly = phases::Link == FinalPhase && Inputs.size() > 0; for (auto &I : Inputs) { types::ID InputType = I.first; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 13842b8cc2870..fdcc7f2b8cfd7 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5342,7 +5342,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-emit-module-interface"); else if (JA.getType() == types::TY_HeaderUnit) CmdArgs.push_back("-emit-header-unit"); - else + else if (!Args.hasArg(options::OPT_ignore_pch)) CmdArgs.push_back("-emit-pch"); } else if (isa<VerifyPCHJobAction>(JA)) { CmdArgs.push_back("-verify-pch"); @@ -5399,7 +5399,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } else if (JA.getType() == types::TY_PP_Asm) { CmdArgs.push_back("-S"); } else if (JA.getType() == types::TY_AST) { - CmdArgs.push_back("-emit-pch"); + if (!Args.hasArg(options::OPT_ignore_pch)) + CmdArgs.push_back("-emit-pch"); } else if (JA.getType() == types::TY_ModuleFile) { CmdArgs.push_back("-module-file-info"); } else if (JA.getType() == types::TY_RewrittenObjC) { diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 19f81ff2fbe9d..e18f897b805b3 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2983,14 +2983,6 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, 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/Driver/ignored-pch.cpp b/clang/test/Driver/ignored-pch.cpp new file mode 100644 index 0000000000000..b237fc3cba57d --- /dev/null +++ b/clang/test/Driver/ignored-pch.cpp @@ -0,0 +1,19 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t + +// Create PCH without -ignore-pch. +// RUN: %clang -x c++-header %S/../Modules/Inputs/codegen-flags/foo.h -### 2>&1 | FileCheck %s -check-prefix=CHECK-EMIT-PCH +// RUN: %clang -x c++-header %S/../Modules/Inputs/codegen-flags/foo.h -o %t/foo.h.pch +// RUN: %clang %s -include-pch %t/foo.h.pch -### 2>&1 | FileCheck %s -check-prefix=CHECK-INCLUDE-PCH +// RUN: %clang %s -emit-ast -include-pch %t/foo.h.pch -### 2>&1 | FileCheck %s -check-prefixes=CHECK-EMIT-PCH,CHECK-INCLUDE-PCH + + +// Create PCH with -ignore-pch. +// RUN: %clang -x c++-header -ignore-pch %S/../Modules/Inputs/codegen-flags/foo.h -### 2>&1 | FileCheck %s -check-prefix=CHECK-IGNORE-PCH +// RUN: %clang %s -ignore-pch -include-pch %t/foo.h.pch -### 2>&1 | FileCheck %s -check-prefix=CHECK-IGNORE-PCH +// RUN: %clang %s -ignore-pch -emit-ast -include-pch %t/foo.h.pch -### 2>&1 | FileCheck %s -check-prefix=CHECK-IGNORE-PCH + +// CHECK-EMIT-PCH: -emit-pch +// CHECK-INCLUDE-PCH: -include-pch +// CHECK-IGNORE-PCH-NOT: -emit-pch +// CHECK-IGNORE-PCH-NOT: -include-pch diff --git a/clang/test/PCH/ignored-pch.c b/clang/test/PCH/ignored-pch.c index 198ad0fde7d05..5b64582cba618 100644 --- a/clang/test/PCH/ignored-pch.c +++ b/clang/test/PCH/ignored-pch.c @@ -1,114 +1,113 @@ // 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: %clang -x c-header %S/Inputs/ignored-pch.h -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -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: %clang -x c-header %S/Inputs/ignored-pch.h -o %t.pch +// RUN: %clang %s -emit-ast -include-pch %t.pch -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 is passed through Driver. +// Check that -ignore-pch causes -emit-pch and -include-pch options to be ignored. // 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: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -o %t.ll +// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-PCH-ERROR %s +// RUN: ls %t.ll 2>&1 | 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 +// RUN: %clang -emit-ast %s -include-pch %t.pch -ignore-pch -o %t.ll +// RUN: not ls %t.ll 2>&1 | FileCheck --check-prefix=CHECK-OBJ-ERROR %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: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -Xclang -building-pch-with-obj -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -Xclang -building-pch-with-obj -o %t.ll +// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-PCH-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: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -Xclang -fallow-pch-with-compiler-errors -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -Xclang -fallow-pch-with-compiler-errors -o %t.ll +// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-PCH-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: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -Xclang -fallow-pch-with-different-modules-cache-path -o %t.pch +// RUN: %clang -S -emit-llvm %s -ignore-pch -include-pch %t.pch -Xclang -fallow-pch-with-different-modules-cache-path -o %t.ll +// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-PCH-ERROR %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: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -fpch-codegen -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -fpch-codegen -o %t.ll +// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-PCH-ERROR %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: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -fpch-debuginfo -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -fpch-debuginfo -o %t.ll +// RUN: not ls %t.pch 2>&1 | 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: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -fpch-instantiate-templates -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -fpch-instantiate-templates -o %t.ll +// RUN: not ls %t.pch 2>&1 | 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: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -Xclang -fno-pch-timestamp -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -Xclang -fno-pch-timestamp -o %t.ll +// RUN: not ls %t.pch 2>&1 | 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: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -Xclang -fno-validate-pch -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -Xclang -fno-validate-pch -o %t.ll +// RUN: not ls %t.pch 2>&1 | 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: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -relocatable-pch -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -relocatable-pch -o %t.ll +// RUN: not ls %t.pch 2>&1 | 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: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -Xclang -pch-through-hdrstop-create -o %t.pch +// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -Xclang -pch-through-hdrstop-use -o %t.ll +// RUN: not ls %t.pch 2>&1 | 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 +// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -o %t.pch +// RUN: %clang %s -include-pch %t.pch -Xclang -ast-dump-all -c | FileCheck --check-prefix=CHECK-AST-PCH %s +// RUN: %clang %s -include-pch %t.pch -ignore-pch -Xclang -ast-dump-all -c | 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-PCH-ERROR: ignored-pch.c.{{.*}}.pch{{'?}}: No such file or directory +// CHECK-OBJ-ERROR: ignored-pch.c.{{.*}}.ll{{'?}}: No such file or directory // CHECK-AST-PCH: <undeserialized declarations> // CHECK-AST-NOT: <undeserialized declarations> -#include "Inputs/ignored-pch.h" #pragma hdrstop +#include "Inputs/ignored-pch.h" int main() { return f(); } >From 8dff812d140fefcda2ff9eb0cbd4aa5b323d7643 Mon Sep 17 00:00:00 2001 From: Ying Yi <ying...@sony.com> Date: Thu, 5 Jun 2025 11:12:27 +0100 Subject: [PATCH 5/6] Update the patch following the reviewer's suggestions. --- clang/docs/PCHInternals.rst | 10 ---------- clang/include/clang/Driver/Options.td | 2 +- clang/lib/Driver/Driver.cpp | 7 +++---- clang/lib/Frontend/CompilerInvocation.cpp | 1 - 4 files changed, 4 insertions(+), 16 deletions(-) diff --git a/clang/docs/PCHInternals.rst b/clang/docs/PCHInternals.rst index f724229102729..079fba16711dc 100644 --- a/clang/docs/PCHInternals.rst +++ b/clang/docs/PCHInternals.rst @@ -31,16 +31,6 @@ option: $ clang -cc1 -include-pch test.h.pch test.c -o test.s -To ignore PCH options, 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/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index dcea81b0099ae..88ab190c5f66d 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3349,7 +3349,7 @@ defm pch_codegen: OptInCC1FFlag<"pch-codegen", "Generate ", "Do not generate ", defm pch_debuginfo: OptInCC1FFlag<"pch-debuginfo", "Generate ", "Do not generate ", "debug info for types in an object file built from this PCH and do not generate them elsewhere">; def ignore_pch : Flag<["-"], "ignore-pch">, Group<f_Group>, - Visibility<[ClangOption, CC1Option]>, + Visibility<[ClangOption]>, HelpText<"Disable precompiled headers, overrides -emit-pch and -include-pch">; def fimplicit_module_maps : Flag <["-"], "fimplicit-module-maps">, Group<f_Group>, diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 34f6cd4a3cd4b..5560c581c3f33 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -4286,14 +4286,13 @@ void Driver::handleArguments(Compilation &C, DerivedArgList &Args, YcArg = YuArg = nullptr; } - Arg *IncludePCHArg = Args.getLastArg(options::OPT_include_pch); - if (IncludePCHArg && (FinalPhase == phases::Preprocess || - Args.hasArg(options::OPT_ignore_pch))) { + if (Args.hasArg(options::OPT_include_pch) && + (FinalPhase == phases::Preprocess || + Args.hasArg(options::OPT_ignore_pch))) { // If only preprocessing or -ignore-pch is used, -include-pch is disabled. // Since -emit-pch is CC1option, it will not be added to command argments if // -ignore-pch is used. Args.eraseArg(options::OPT_include_pch); - IncludePCHArg = nullptr; } bool LinkOnly = phases::Link == FinalPhase && Inputs.size() > 0; diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index e18f897b805b3..2c02719121c73 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2982,7 +2982,6 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, #undef FRONTEND_OPTION_WITH_MARSHALLING Opts.ProgramAction = frontend::ParseSyntaxOnly; - if (const Arg *A = Args.getLastArg(OPT_Action_Group)) { OptSpecifier Opt = OptSpecifier(A->getOption().getID()); std::optional<frontend::ActionKind> ProgramAction = getFrontendAction(Opt); >From 5d520aa2157dcd013045c5017404db482f4de1d8 Mon Sep 17 00:00:00 2001 From: Ying Yi <ying...@sony.com> Date: Thu, 5 Jun 2025 12:29:21 +0100 Subject: [PATCH 6/6] Revert "Fix an error of unexpected indentation." This reverts commit a3da3bc79589919840c93f4ccc0201a1b9027fb3. --- clang/include/clang/Basic/DiagnosticGroups.td | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index beda73e675fc6..be75b9ee6e3f6 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -813,19 +813,19 @@ changes to one object won't affect the others, the object's initializer will run once per copy, etc. Specifically, this warning fires when it detects an object which: -1. Is defined as ``inline`` in a header file (so it might get compiled into multiple libaries), and -2. Has external linkage (otherwise it's supposed to be duplicated), and -3. Has hidden visibility. + 1. Is defined as ``inline`` in a header file (so it might get compiled into multiple libaries), and + 2. Has external linkage (otherwise it's supposed to be duplicated), and + 3. Has hidden visibility. As well as one of the following: -1. The object is mutable, or -2. The object's initializer definitely has side effects. + 1. The object is mutable, or + 2. The object's initializer definitely has side effects. The warning can be resolved by removing one of the conditions above. In rough order of preference, this may be done by: -1. Marking the object ``const`` (if possible) -2. Moving the object's definition to a source file -3. Giving the object non-hidden visibility, e.g. using ``__attribute((visibility("default")))``. + 1. Marking the object ``const`` (if possible) + 2. Moving the object's definition to a source file + 3. Giving the object non-hidden visibility, e.g. using ``__attribute((visibility("default")))``. Note that for (2), all levels of a pointer variable must be constant; ``const int*`` will trigger the warning because the pointer itself is mutable. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits