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>; + +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>; +def funique_source_file_output_paths: Joined<["-"], "funique-source-file-output-paths">, Group, + HelpText<"Use the output path as the source file identifier for -funique-source-file-names">; def funsigned_bitfields : Flag<["-"], "funsigned-bitfields">, Group; def funsigned_char : Flag<["-"], "funsigned-char">, 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"