-
Notifications
You must be signed in to change notification settings - Fork 14.8k
[clang] Add -funique-source-file-output-paths option #161022
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There's build setups where source file names aren't necessarily unique (e.g. the same source files can be used for multiple targets) but output paths are. It's theoretically possible to get the build system to pass `-funique-source-file-identifier` with the output path, but it can also be quite complicated to do so. Introduce a driver option that specifies the output path as the unique source identifier to support this.
@llvm/pr-subscribers-clang Author: Shoaib Meenai (smeenai) ChangesThere's build setups where source file names aren't necessarily unique Full diff: https://github.com/llvm/llvm-project/pull/161022.diff 5 Files Affected:
diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index a8bbf146431ea..674af675a4336 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -2341,10 +2341,11 @@ are listed below.
When enabled, allows the compiler to assume that each object file
passed to the linker has a unique identifier. The identifier for
- an object file is either the source file path or the value of the
- argument `-funique-source-file-identifier` if specified. This is
- useful for reducing link times when doing ThinLTO in combination with
- whole-program devirtualization or CFI.
+ an object file is either the source file path, the output file path
+ if the ``-funique-source-file-output-paths`` argument is passed, or
+ the value of the argument ``-funique-source-file-identifier`` if
+ specified. This is useful for reducing link times when doing ThinLTO
+ in combination with whole-program devirtualization or CFI.
The full source path or identifier passed to the compiler must be
unique. This means that, for example, the following is a usage error:
@@ -2371,9 +2372,14 @@ are listed below.
.. option:: -funique-source-file-identifier=IDENTIFIER
- Used with `-funique-source-file-names` to specify a source file
+ Used with ``-funique-source-file-names`` to specify a source file
identifier.
+.. option:: -funique-source-file-output-paths
+
+ Used with ``-funique-source-file-names`` to specify the output path
+ as the source file identifier.
+
.. option:: -fforce-emit-vtables
In order to improve devirtualization, forces emitting of vtables even in
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index ceb69091b2a51..4af84703c469c 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -890,4 +890,7 @@ def warn_drv_gcc_install_dir_libstdcxx : Warning<
"future releases of the clang compiler will prefer GCC installations "
"containing libstdc++ include directories; '%0' would be chosen over '%1'">,
InGroup<DiagGroup<"gcc-install-dir-libstdcxx">>;
+
+def err_drv_no_output_filename : Error<
+ "option '%0' requires an output file name">;
}
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 6245cf33a0719..3d173785b8c6e 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4354,6 +4354,8 @@ def unique_source_file_identifier_EQ: Joined<["-"], "funique-source-file-identif
HelpText<"Specify the source file identifier for -funique-source-file-names; "
"uses the source file path if not specified">,
MarshallingInfoString<CodeGenOpts<"UniqueSourceFileIdentifier">>;
+def funique_source_file_output_paths: Joined<["-"], "funique-source-file-output-paths">, Group<f_Group>,
+ HelpText<"Use the output path as the source file identifier for -funique-source-file-names">;
def funsigned_bitfields : Flag<["-"], "funsigned-bitfields">, Group<f_Group>;
def funsigned_char : Flag<["-"], "funsigned-char">, Group<f_Group>;
def fno_unsigned_char : Flag<["-"], "fno-unsigned-char">;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index adaa6b3005577..bf9b49670bfd1 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7578,11 +7578,21 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasFlag(options::OPT_funique_source_file_names,
options::OPT_fno_unique_source_file_names, false)) {
- if (Arg *A = Args.getLastArg(options::OPT_unique_source_file_identifier_EQ))
- A->render(Args, CmdArgs);
- else
+ Arg *A = Args.getLastArg(options::OPT_unique_source_file_identifier_EQ,
+ options::OPT_funique_source_file_output_paths);
+ if (!A) {
CmdArgs.push_back(Args.MakeArgString(
Twine("-funique-source-file-identifier=") + Input.getBaseInput()));
+ } else if (A->getOption().matches(
+ options::OPT_funique_source_file_output_paths)) {
+ if (Output.isFilename())
+ CmdArgs.push_back(Args.MakeArgString(
+ Twine("-funique-source-file-identifier=") + Output.getFilename()));
+ else
+ D.Diag(diag::err_drv_no_output_filename) << A->getSpelling();
+ } else {
+ A->render(Args, CmdArgs);
+ }
}
// Setup statistics file output.
diff --git a/clang/test/Driver/unique-source-file-names.c b/clang/test/Driver/unique-source-file-names.c
index 0dc71345d745c..48403327686b7 100644
--- a/clang/test/Driver/unique-source-file-names.c
+++ b/clang/test/Driver/unique-source-file-names.c
@@ -9,3 +9,9 @@
// ID: "-cc1"
// ID: "-funique-source-file-identifier=foo"
+
+// RUN: %clang -funique-source-file-names -funique-source-file-output-paths -o out.o -c -### %s 2> %t
+// RUN: FileCheck --check-prefix=OUTPUT < %t %s
+
+// OUTPUT: "-cc1"
+// OUTPUT: "-funique-source-file-identifier=out.o"
|
@llvm/pr-subscribers-clang-driver Author: Shoaib Meenai (smeenai) ChangesThere's build setups where source file names aren't necessarily unique Full diff: https://github.com/llvm/llvm-project/pull/161022.diff 5 Files Affected:
diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index a8bbf146431ea..674af675a4336 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -2341,10 +2341,11 @@ are listed below.
When enabled, allows the compiler to assume that each object file
passed to the linker has a unique identifier. The identifier for
- an object file is either the source file path or the value of the
- argument `-funique-source-file-identifier` if specified. This is
- useful for reducing link times when doing ThinLTO in combination with
- whole-program devirtualization or CFI.
+ an object file is either the source file path, the output file path
+ if the ``-funique-source-file-output-paths`` argument is passed, or
+ the value of the argument ``-funique-source-file-identifier`` if
+ specified. This is useful for reducing link times when doing ThinLTO
+ in combination with whole-program devirtualization or CFI.
The full source path or identifier passed to the compiler must be
unique. This means that, for example, the following is a usage error:
@@ -2371,9 +2372,14 @@ are listed below.
.. option:: -funique-source-file-identifier=IDENTIFIER
- Used with `-funique-source-file-names` to specify a source file
+ Used with ``-funique-source-file-names`` to specify a source file
identifier.
+.. option:: -funique-source-file-output-paths
+
+ Used with ``-funique-source-file-names`` to specify the output path
+ as the source file identifier.
+
.. option:: -fforce-emit-vtables
In order to improve devirtualization, forces emitting of vtables even in
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index ceb69091b2a51..4af84703c469c 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -890,4 +890,7 @@ def warn_drv_gcc_install_dir_libstdcxx : Warning<
"future releases of the clang compiler will prefer GCC installations "
"containing libstdc++ include directories; '%0' would be chosen over '%1'">,
InGroup<DiagGroup<"gcc-install-dir-libstdcxx">>;
+
+def err_drv_no_output_filename : Error<
+ "option '%0' requires an output file name">;
}
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 6245cf33a0719..3d173785b8c6e 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4354,6 +4354,8 @@ def unique_source_file_identifier_EQ: Joined<["-"], "funique-source-file-identif
HelpText<"Specify the source file identifier for -funique-source-file-names; "
"uses the source file path if not specified">,
MarshallingInfoString<CodeGenOpts<"UniqueSourceFileIdentifier">>;
+def funique_source_file_output_paths: Joined<["-"], "funique-source-file-output-paths">, Group<f_Group>,
+ HelpText<"Use the output path as the source file identifier for -funique-source-file-names">;
def funsigned_bitfields : Flag<["-"], "funsigned-bitfields">, Group<f_Group>;
def funsigned_char : Flag<["-"], "funsigned-char">, Group<f_Group>;
def fno_unsigned_char : Flag<["-"], "fno-unsigned-char">;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index adaa6b3005577..bf9b49670bfd1 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7578,11 +7578,21 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasFlag(options::OPT_funique_source_file_names,
options::OPT_fno_unique_source_file_names, false)) {
- if (Arg *A = Args.getLastArg(options::OPT_unique_source_file_identifier_EQ))
- A->render(Args, CmdArgs);
- else
+ Arg *A = Args.getLastArg(options::OPT_unique_source_file_identifier_EQ,
+ options::OPT_funique_source_file_output_paths);
+ if (!A) {
CmdArgs.push_back(Args.MakeArgString(
Twine("-funique-source-file-identifier=") + Input.getBaseInput()));
+ } else if (A->getOption().matches(
+ options::OPT_funique_source_file_output_paths)) {
+ if (Output.isFilename())
+ CmdArgs.push_back(Args.MakeArgString(
+ Twine("-funique-source-file-identifier=") + Output.getFilename()));
+ else
+ D.Diag(diag::err_drv_no_output_filename) << A->getSpelling();
+ } else {
+ A->render(Args, CmdArgs);
+ }
}
// Setup statistics file output.
diff --git a/clang/test/Driver/unique-source-file-names.c b/clang/test/Driver/unique-source-file-names.c
index 0dc71345d745c..48403327686b7 100644
--- a/clang/test/Driver/unique-source-file-names.c
+++ b/clang/test/Driver/unique-source-file-names.c
@@ -9,3 +9,9 @@
// ID: "-cc1"
// ID: "-funique-source-file-identifier=foo"
+
+// RUN: %clang -funique-source-file-names -funique-source-file-output-paths -o out.o -c -### %s 2> %t
+// RUN: FileCheck --check-prefix=OUTPUT < %t %s
+
+// OUTPUT: "-cc1"
+// OUTPUT: "-funique-source-file-identifier=out.o"
|
Ping. |
What do you think about |
I like that more; I'll rework the diff accordingly.
It might be cleaner to do this bit first; I can put that up as a prerequisite PR if that turns out to be the case. |
There's build setups where source file names aren't necessarily unique
(e.g. the same source files can be used for multiple targets) but output
paths are. It's theoretically possible to get the build system to pass
-funique-source-file-identifier
with the output path, but it can alsobe quite complicated to do so. Introduce a driver option that specifies
the output path as the unique source identifier to support this.