Skip to content

Commit 4fb81f1

Browse files
authored
[Frontend][PCH]-Add support for ignoring PCH options (-ignore-pch). (#142409)
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). The commit includes: 1. Implement -ignore-pch as a Driver option. 2. Add a Driver test and a PCH test. 3. Add a section of -ignore-pch to user manual. 4. Add a release note for the new option '-ignore-pch'. Code reviewed by: Matheus Izvekov <[email protected]>
1 parent 5955f3e commit 4fb81f1

File tree

8 files changed

+168
-2
lines changed

8 files changed

+168
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,8 @@ New Compiler Flags
339339

340340
- New option ``-Wnrvo`` added and disabled by default to warn about missed NRVO opportunities.
341341

342+
- New option ``-ignore-pch`` added to disable precompiled headers. It overrides ``-emit-pch`` and ``-include-pch``. (#GH142409, `PCHDocs <https://clang.llvm.org/docs/UsersManual.html#ignoring-a-pch-file>`_).
343+
342344
Deprecated Compiler Flags
343345
-------------------------
344346

clang/docs/UsersManual.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,6 +1458,19 @@ will be processed from the PCH file. Otherwise, Clang will report an error.
14581458
``test.h`` since ``test.h`` was included directly in the source file and not
14591459
specified on the command line using ``-include-pch``.
14601460

1461+
Ignoring a PCH File
1462+
^^^^^^^^^^^^^^^^^^^
1463+
1464+
To ignore PCH options, a `-ignore-pch` option is passed to ``clang``:
1465+
1466+
.. code-block:: console
1467+
1468+
$ clang -x c-header test.h -Xclang -ignore-pch -o test.h.pch
1469+
$ clang -include-pch test.h.pch -Xclang -ignore-pch test.c -o test
1470+
1471+
This option disables precompiled headers, overrides -emit-pch and -include-pch.
1472+
test.h.pch is not generated and not used as a prefix header.
1473+
14611474
Relocatable PCH Files
14621475
^^^^^^^^^^^^^^^^^^^^^
14631476

clang/include/clang/Driver/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3348,6 +3348,9 @@ defm pch_codegen: OptInCC1FFlag<"pch-codegen", "Generate ", "Do not generate ",
33483348
"code for uses of this PCH that assumes an explicit object file will be built for the PCH">;
33493349
defm pch_debuginfo: OptInCC1FFlag<"pch-debuginfo", "Generate ", "Do not generate ",
33503350
"debug info for types in an object file built from this PCH and do not generate them elsewhere">;
3351+
def ignore_pch : Flag<["-"], "ignore-pch">, Group<f_Group>,
3352+
Visibility<[ClangOption]>,
3353+
HelpText<"Disable precompiled headers, overrides -emit-pch and -include-pch">;
33513354

33523355
def fimplicit_module_maps : Flag <["-"], "fimplicit-module-maps">, Group<f_Group>,
33533356
Visibility<[ClangOption, CC1Option, CLOption]>,

clang/lib/Driver/Driver.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4331,6 +4331,15 @@ void Driver::handleArguments(Compilation &C, DerivedArgList &Args,
43314331
YcArg = YuArg = nullptr;
43324332
}
43334333

4334+
if (Args.hasArg(options::OPT_include_pch) &&
4335+
(FinalPhase == phases::Preprocess ||
4336+
Args.hasArg(options::OPT_ignore_pch))) {
4337+
// If only preprocessing or -ignore-pch is used, -include-pch is disabled.
4338+
// Since -emit-pch is CC1option, it will not be added to command argments if
4339+
// -ignore-pch is used.
4340+
Args.eraseArg(options::OPT_include_pch);
4341+
}
4342+
43344343
bool LinkOnly = phases::Link == FinalPhase && Inputs.size() > 0;
43354344
for (auto &I : Inputs) {
43364345
types::ID InputType = I.first;

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5321,7 +5321,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
53215321
CmdArgs.push_back("-emit-module-interface");
53225322
else if (JA.getType() == types::TY_HeaderUnit)
53235323
CmdArgs.push_back("-emit-header-unit");
5324-
else
5324+
else if (!Args.hasArg(options::OPT_ignore_pch))
53255325
CmdArgs.push_back("-emit-pch");
53265326
} else if (isa<VerifyPCHJobAction>(JA)) {
53275327
CmdArgs.push_back("-verify-pch");
@@ -5378,7 +5378,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
53785378
} else if (JA.getType() == types::TY_PP_Asm) {
53795379
CmdArgs.push_back("-S");
53805380
} else if (JA.getType() == types::TY_AST) {
5381-
CmdArgs.push_back("-emit-pch");
5381+
if (!Args.hasArg(options::OPT_ignore_pch))
5382+
CmdArgs.push_back("-emit-pch");
53825383
} else if (JA.getType() == types::TY_ModuleFile) {
53835384
CmdArgs.push_back("-module-file-info");
53845385
} else if (JA.getType() == types::TY_RewrittenObjC) {

clang/test/Driver/ignored-pch.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: rm -rf %t
2+
// RUN: mkdir -p %t
3+
4+
// Create PCH without -ignore-pch.
5+
// RUN: %clang -x c++-header %S/../Modules/Inputs/codegen-flags/foo.h -### 2>&1 | FileCheck %s -check-prefix=CHECK-EMIT-PCH
6+
// RUN: %clang -x c++-header %S/../Modules/Inputs/codegen-flags/foo.h -o %t/foo.h.pch
7+
// RUN: %clang %s -include-pch %t/foo.h.pch -### 2>&1 | FileCheck %s -check-prefix=CHECK-INCLUDE-PCH
8+
// RUN: %clang %s -emit-ast -include-pch %t/foo.h.pch -### 2>&1 | FileCheck %s -check-prefixes=CHECK-EMIT-PCH,CHECK-INCLUDE-PCH
9+
10+
11+
// Create PCH with -ignore-pch.
12+
// RUN: %clang -x c++-header -ignore-pch %S/../Modules/Inputs/codegen-flags/foo.h -### 2>&1 | FileCheck %s -check-prefix=CHECK-IGNORE-PCH
13+
// RUN: %clang %s -ignore-pch -include-pch %t/foo.h.pch -### 2>&1 | FileCheck %s -check-prefix=CHECK-IGNORE-PCH
14+
// RUN: %clang %s -ignore-pch -emit-ast -include-pch %t/foo.h.pch -### 2>&1 | FileCheck %s -check-prefix=CHECK-IGNORE-PCH
15+
16+
// CHECK-EMIT-PCH: -emit-pch
17+
// CHECK-INCLUDE-PCH: -include-pch
18+
// CHECK-IGNORE-PCH-NOT: -emit-pch
19+
// CHECK-IGNORE-PCH-NOT: -include-pch

clang/test/PCH/Inputs/ignored-pch.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef IGNORED_PCH_H
2+
#define IGNORED_PCH_H
3+
inline int f() {
4+
return 42;
5+
}
6+
#endif // IGNORED_PCH_H

clang/test/PCH/ignored-pch.c

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// RUN: rm -rf %t.pch %t.ll
2+
// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -o %t.pch
3+
// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -o %t.ll
4+
// RUN: ls %t.pch | FileCheck --check-prefix=CHECK-PCH %s
5+
// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s
6+
7+
// RUN: rm -rf %t.pch %t.ll
8+
// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -o %t.pch
9+
// RUN: %clang %s -emit-ast -include-pch %t.pch -o %t.ll
10+
// RUN: ls %t.pch | FileCheck --check-prefix=CHECK-PCH %s
11+
// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s
12+
13+
// Check that -ignore-pch causes -emit-pch and -include-pch options to be ignored.
14+
// RUN: rm -rf %t.pch %t.ll
15+
// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -o %t.pch
16+
// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -o %t.ll
17+
// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-PCH-ERROR %s
18+
// RUN: ls %t.ll 2>&1 | FileCheck --check-prefix=CHECK-OBJ %s
19+
20+
// RUN: rm -rf %t.pch %t.ll
21+
// RUN: %clang -emit-ast %s -include-pch %t.pch -ignore-pch -o %t.ll
22+
// RUN: not ls %t.ll 2>&1 | FileCheck --check-prefix=CHECK-OBJ-ERROR %s
23+
24+
// Check that -ignore-pch works for multiple PCH related options.
25+
// Test with -building-pch-with-obj.
26+
// RUN: rm -rf %t.pch %t.ll
27+
// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -Xclang -building-pch-with-obj -o %t.pch
28+
// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -Xclang -building-pch-with-obj -o %t.ll
29+
// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-PCH-ERROR %s
30+
// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s
31+
32+
// Test with -fallow-pch-with-compiler-errors.
33+
// RUN: rm -rf %t.pch %t.ll
34+
// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -Xclang -fallow-pch-with-compiler-errors -o %t.pch
35+
// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -Xclang -fallow-pch-with-compiler-errors -o %t.ll
36+
// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-PCH-ERROR %s
37+
// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s
38+
39+
// Test with -fallow-pch-with-different-modules-cache-path.
40+
// RUN: rm -rf %t.pch %t.ll
41+
// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -Xclang -fallow-pch-with-different-modules-cache-path -o %t.pch
42+
// RUN: %clang -S -emit-llvm %s -ignore-pch -include-pch %t.pch -Xclang -fallow-pch-with-different-modules-cache-path -o %t.ll
43+
// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-PCH-ERROR %s
44+
// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s
45+
46+
// Test with -fpch-codegen.
47+
// RUN: rm -rf %t.pch %t.ll
48+
// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -fpch-codegen -o %t.pch
49+
// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -fpch-codegen -o %t.ll
50+
// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-PCH-ERROR %s
51+
// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s
52+
53+
// Test with -fpch-debuginfo.
54+
// RUN: rm -rf %t.pch %t.ll
55+
// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -fpch-debuginfo -o %t.pch
56+
// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -fpch-debuginfo -o %t.ll
57+
// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-PCH %s
58+
// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s
59+
60+
// Test with -fpch-instantiate-templates.
61+
// RUN: rm -rf %t.pch %t.ll
62+
// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -fpch-instantiate-templates -o %t.pch
63+
// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -fpch-instantiate-templates -o %t.ll
64+
// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-PCH %s
65+
// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s
66+
67+
// Test with -fno-pch-timestamp.
68+
// RUN: rm -rf %t.pch %t.ll
69+
// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -Xclang -fno-pch-timestamp -o %t.pch
70+
// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -Xclang -fno-pch-timestamp -o %t.ll
71+
// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-PCH %s
72+
// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s
73+
74+
// Test with -fno-validate-pch.
75+
// RUN: rm -rf %t.pch %t.ll
76+
// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -Xclang -fno-validate-pch -o %t.pch
77+
// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -Xclang -fno-validate-pch -o %t.ll
78+
// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-PCH %s
79+
// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s
80+
81+
// Test with -relocatable-pch.
82+
// RUN: rm -rf %t.pch %t.ll
83+
// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -relocatable-pch -o %t.pch
84+
// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -relocatable-pch -o %t.ll
85+
// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-PCH %s
86+
// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s
87+
88+
// Test with -pch-through-hdrstop-create/-pch-through-hdrstop-use
89+
// RUN: rm -rf %t.pch %t.ll
90+
// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -ignore-pch -Xclang -pch-through-hdrstop-create -o %t.pch
91+
// RUN: %clang -S -emit-llvm %s -include-pch %t.pch -ignore-pch -Xclang -pch-through-hdrstop-use -o %t.ll
92+
// RUN: not ls %t.pch 2>&1 | FileCheck --check-prefix=CHECK-PCH %s
93+
// RUN: ls %t.ll | FileCheck --check-prefix=CHECK-OBJ %s
94+
95+
96+
// Test with AST dump output:
97+
// RUN: rm -rf %t.pch %t.ll
98+
// RUN: %clang -x c-header %S/Inputs/ignored-pch.h -o %t.pch
99+
// RUN: %clang %s -include-pch %t.pch -Xclang -ast-dump-all -c | FileCheck --check-prefix=CHECK-AST-PCH %s
100+
// RUN: %clang %s -include-pch %t.pch -ignore-pch -Xclang -ast-dump-all -c | FileCheck --check-prefix=CHECK-AST %s
101+
102+
// CHECK-PCH: ignored-pch.c.{{.*}}.pch
103+
// CHECK-OBJ: ignored-pch.c.{{.*}}.ll
104+
// CHECK-PCH-ERROR: ignored-pch.c.{{.*}}.pch{{'?}}: No such file or directory
105+
// CHECK-OBJ-ERROR: ignored-pch.c.{{.*}}.ll{{'?}}: No such file or directory
106+
// CHECK-AST-PCH: <undeserialized declarations>
107+
// CHECK-AST-NOT: <undeserialized declarations>
108+
109+
#pragma hdrstop
110+
#include "Inputs/ignored-pch.h"
111+
int main() {
112+
return f();
113+
}

0 commit comments

Comments
 (0)