Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -115,6 +115,23 @@ if the source header file is not self-contained. This option is enabled by default for clang-cl. +- -fpch-codegen and -fpch-debuginfo generate shared code and/or debuginfo + for contents of a precompiled header in a separate object file. This object + file needs to be linked in, but its contents do not need to be generated + by other objects using the precompiled header. This should usually save + compile time. If not using clang-cl, the separate object file needs to + be created explicitly by compiling an empty source file that only uses + the precompiled header. Since headers may bring in private symbols + of other libraries, it may be necessary to discard unused symbols. + Example of use: + + .. code-block:: console + + $ clang++ -x c++-header header.h -o header.pch -fpch-codegen -fpch-debuginfo + $ clang++ -c empty.cpp -o shared.o -include-pch header.pch -fpch-codegen -fpch-debuginfo -fdata-sections -ffunction-sections + $ clang++ -c source.cpp -o source.o -include-pch header.pch + $ clang++ -o binary source.o shared.o -Wl,--gc-sections + Deprecated Compiler Flags ------------------------- Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -1440,6 +1440,22 @@ def fno_pch_instantiate_templates: Flag <["-"], "fno-pch-instantiate-templates">, Group, Flags<[CC1Option]>; +def fpch_codegen: + Flag<["-"], "fpch-codegen">, + Group, Flags<[CC1Option]>, + HelpText<"Generate code for uses of this PCH that assumes an explicit " + "object file will be built for the PCH">; +def fno_pch_codegen: + Flag<["-"], "fno-pch-codegen">, + Group, Flags<[CC1Option]>; +def fpch_debuginfo: + Flag<["-"], "fpch-debuginfo">, + Group, Flags<[CC1Option]>, + HelpText<"Generate debug info for types in an object file built from this " + "PCH and do not generate them elsewhere">; +def fno_pch_debuginfo: + Flag<["-"], "fno-pch-debuginfo">, + Group, Flags<[CC1Option]>; def fmodules : Flag <["-"], "fmodules">, Group, Flags<[DriverOption, CC1Option]>, Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -5627,6 +5627,16 @@ if (Args.hasFlag(options::OPT_fpch_instantiate_templates, options::OPT_fno_pch_instantiate_templates, false)) CmdArgs.push_back("-fpch-instantiate-templates"); + if (Args.hasFlag(options::OPT_fpch_codegen, options::OPT_fno_pch_codegen, + false)) { + CmdArgs.push_back("-fpch-codegen"); + CmdArgs.push_back("-building-pch-with-obj"); + } + if (Args.hasFlag(options::OPT_fpch_debuginfo, options::OPT_fno_pch_debuginfo, + false)) { + CmdArgs.push_back("-fpch-debuginfo"); + CmdArgs.push_back("-building-pch-with-obj"); + } Args.AddLastArg(CmdArgs, options::OPT_fexperimental_new_pass_manager, options::OPT_fno_experimental_new_pass_manager); Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -2877,8 +2877,10 @@ Opts.ModulesLocalVisibility = Args.hasArg(OPT_fmodules_local_submodule_visibility) || Opts.ModulesTS || Opts.CPlusPlusModules; - Opts.ModulesCodegen = Args.hasArg(OPT_fmodules_codegen); - Opts.ModulesDebugInfo = Args.hasArg(OPT_fmodules_debuginfo); + Opts.ModulesCodegen = + Args.hasArg(OPT_fmodules_codegen) || Args.hasArg(OPT_fpch_codegen); + Opts.ModulesDebugInfo = + Args.hasArg(OPT_fmodules_debuginfo) || Args.hasArg(OPT_fpch_debuginfo); Opts.ModulesSearchAll = Opts.Modules && !Args.hasArg(OPT_fno_modules_search_all) && Args.hasArg(OPT_fmodules_search_all); Index: clang/test/PCH/codegen.cpp =================================================================== --- clang/test/PCH/codegen.cpp +++ clang/test/PCH/codegen.cpp @@ -6,37 +6,47 @@ // RUN: mkdir -p %t // REQUIRES: x86-registered-target -// RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-codegen -x c++-header -building-pch-with-obj -emit-pch %S/../Modules/Inputs/codegen-flags/foo.h -o %t/foo-cg.pch -// RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-debuginfo -x c++-header -building-pch-with-obj -emit-pch %S/../Modules/Inputs/codegen-flags/foo.h -o %t/foo-di.pch +// RUN: %clang_cc1 -triple x86_64-linux-gnu -fpch-codegen -x c++-header -building-pch-with-obj -emit-pch %S/../Modules/Inputs/codegen-flags/foo.h -o %t/foo-cg.pch +// RUN: %clang_cc1 -triple x86_64-linux-gnu -fpch-debuginfo -x c++-header -building-pch-with-obj -emit-pch %S/../Modules/Inputs/codegen-flags/foo.h -o %t/foo-di.pch -// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %s -include-pch %t/foo-cg.pch -building-pch-with-obj -fmodules-codegen | FileCheck --check-prefix=CG %s -// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %s -include-pch %t/foo-di.pch -building-pch-with-obj -fmodules-debuginfo | FileCheck --check-prefix=DI %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %s -include-pch %t/foo-cg.pch -building-pch-with-obj -fpch-codegen | FileCheck --check-prefix=CG %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %s -include-pch %t/foo-di.pch -building-pch-with-obj -fpch-debuginfo | FileCheck --check-prefix=DI %s // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -include-pch %t/foo-cg.pch %S/../Modules/Inputs/codegen-flags/use.cpp | FileCheck --check-prefix=CG-USE %s // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -include-pch %t/foo-di.pch %S/../Modules/Inputs/codegen-flags/use.cpp | FileCheck --check-prefix=DI-USE %s // Test with template instantiation in the pch. -// RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-codegen -x c++-header -building-pch-with-obj -emit-pch -fpch-instantiate-templates %S/../Modules/Inputs/codegen-flags/foo.h -o %t/foo-cg.pch -// RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-debuginfo -x c++-header -building-pch-with-obj -emit-pch -fpch-instantiate-templates %S/../Modules/Inputs/codegen-flags/foo.h -o %t/foo-di.pch +// RUN: %clang_cc1 -triple x86_64-linux-gnu -fpch-codegen -x c++-header -building-pch-with-obj -emit-pch -fpch-instantiate-templates %S/../Modules/Inputs/codegen-flags/foo.h -o %t/foo-cg.pch +// RUN: %clang_cc1 -triple x86_64-linux-gnu -fpch-debuginfo -x c++-header -building-pch-with-obj -emit-pch -fpch-instantiate-templates %S/../Modules/Inputs/codegen-flags/foo.h -o %t/foo-di.pch -// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %s -include-pch %t/foo-cg.pch -building-pch-with-obj -fmodules-codegen | FileCheck --check-prefix=CG %s -// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %s -include-pch %t/foo-di.pch -building-pch-with-obj -fmodules-debuginfo | FileCheck --check-prefix=DI %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %s -include-pch %t/foo-cg.pch -building-pch-with-obj -fpch-codegen | FileCheck --check-prefix=CG %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %s -include-pch %t/foo-di.pch -building-pch-with-obj -fpch-debuginfo | FileCheck --check-prefix=DI %s // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -include-pch %t/foo-cg.pch %S/../Modules/Inputs/codegen-flags/use.cpp | FileCheck --check-prefix=CG-USE %s // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -include-pch %t/foo-di.pch %S/../Modules/Inputs/codegen-flags/use.cpp | FileCheck --check-prefix=DI-USE %s +// Test using the driver. -// CG: define weak_odr void @_Z2f1v +// RUN: %clang -target x86_64-linux-gnu -fpch-codegen -x c++-header -fpch-instantiate-templates %S/../Modules/Inputs/codegen-flags/foo.h -o %t/foo-cg.pch +// RUN: %clang -target x86_64-linux-gnu -fpch-debuginfo -x c++-header -fpch-instantiate-templates %S/../Modules/Inputs/codegen-flags/foo.h -o %t/foo-di.pch + +// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -g -o - %s -include-pch %t/foo-cg.pch -fpch-codegen | FileCheck --check-prefix=CG %s +// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -g -o - %s -include-pch %t/foo-di.pch -fpch-debuginfo | FileCheck --check-prefix=DI %s + +// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -g -o - -include-pch %t/foo-cg.pch %S/../Modules/Inputs/codegen-flags/use.cpp | FileCheck --check-prefix=CG-USE %s +// RUN: %clang -target x86_64-linux-gnu -S -emit-llvm -g -o - -include-pch %t/foo-di.pch %S/../Modules/Inputs/codegen-flags/use.cpp | FileCheck --check-prefix=DI-USE %s + +// CG: define weak_odr {{(dso_local )?}}void @_Z2f1v // CG: DICompileUnit // CG-NOT: DICompositeType -// CG-USE: declare void @_Z2f1v +// CG-USE: declare {{(dso_local )?}}void @_Z2f1v // CG-USE: DICompileUnit // CG-USE: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo" // DI-NOT: define // DI: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo" -// DI-USE: define linkonce_odr void @_Z2f1v +// DI-USE: define linkonce_odr {{(dso_local )?}}void @_Z2f1v // DI-USE: = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", {{.*}}, flags: DIFlagFwdDecl