diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 4ec4e4a49de6b..c0820bd01fd5f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -192,12 +192,20 @@ New Compiler Flags - The flag ``-std=c++23`` has been added. This behaves the same as the existing flag ``-std=c++2b``. +- ``-dumpdir`` has been implemented to specify auxiliary and dump output + filenames for features like ``-gsplit-dwarf``. + Deprecated Compiler Flags ------------------------- Modified Compiler Flags ----------------------- +- ``clang -g -gsplit-dwarf a.c -o obj/x`` (compile and link) now generates the + ``.dwo`` file at ``obj/x-a.dwo``, instead of a file in the temporary + directory (``/tmp`` on \*NIX systems, if none of the environment variables + TMPDIR, TMP, and TEMP are specified). + Removed Compiler Flags ------------------------- - The deprecated flag `-fmodules-ts` is removed. Please use ``-std=c++20`` diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 496264b74d460..670003a3da847 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1142,6 +1142,10 @@ def module_dependency_dir : Separate<["-"], "module-dependency-dir">, def dsym_dir : JoinedOrSeparate<["-"], "dsym-dir">, Flags<[NoXarchOption, RenderAsInput]>, HelpText<"Directory to output dSYM's (if any) to">, MetaVarName<"">; +// GCC style -dumpdir. We intentionally don't implement the less useful -dumpbase{,-ext}. +def dumpdir : Separate<["-"], "dumpdir">, Flags<[CC1Option]>, + MetaVarName<"">, + HelpText<"Use as a prefix to form auxiliary and dump file names">; def dumpmachine : Flag<["-"], "dumpmachine">; def dumpspecs : Flag<["-"], "dumpspecs">, Flags<[Unsupported]>; def dumpversion : Flag<["-"], "dumpversion">; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index a2deb9b0dd9ad..879f3bf00d1cf 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -3878,6 +3878,21 @@ void Driver::handleArguments(Compilation &C, DerivedArgList &Args, !Args.getLastArgValue(options::OPT_fuse_ld_EQ) .equals_insensitive("lld")) Diag(clang::diag::err_drv_lto_without_lld); + + // If -dumpdir is not specified, give a default prefix derived from the link + // output filename. For example, `clang -g -gsplit-dwarf a.c -o x` passes + // `-dumpdir x-` to cc1. If -o is unspecified, use + // stem(getDefaultImageName()) (usually stem("a.out") = "a"). + if (!Args.hasArg(options::OPT_dumpdir)) { + Arg *Arg = Args.MakeSeparateArg( + nullptr, getOpts().getOption(options::OPT_dumpdir), + Args.MakeArgString(Args.getLastArgValue( + options::OPT_o, + llvm::sys::path::stem(getDefaultImageName())) + + "-")); + Arg->claim(); + Args.append(Arg); + } } if (FinalPhase == phases::Preprocess || Args.hasArg(options::OPT__SLASH_Y_)) { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index c12a6ab88097b..a518cc487cfd5 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4854,6 +4854,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } + Args.AddLastArg(CmdArgs, options::OPT_dumpdir); + if (const Arg *A = Args.getLastArg(options::OPT_fthinlto_index_EQ)) { if (!types::isLLVMIR(Input.getType())) D.Diag(diag::err_drv_arg_requires_bitcode_input) << A->getAsString(Args); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index cf21d6243b180..a6247b4cbe4ea 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1248,23 +1248,24 @@ const char *tools::SplitDebugName(const JobAction &JA, const ArgList &Args, if (StringRef(A->getValue()) == "single") return Args.MakeArgString(Output.getFilename()); - Arg *FinalOutput = Args.getLastArg(options::OPT_o); - if (FinalOutput && Args.hasArg(options::OPT_c)) { - SmallString<128> T(FinalOutput->getValue()); - llvm::sys::path::remove_filename(T); - llvm::sys::path::append(T, llvm::sys::path::stem(FinalOutput->getValue())); - AddPostfix(T); - return Args.MakeArgString(T); + SmallString<128> T; + if (const Arg *A = Args.getLastArg(options::OPT_dumpdir)) { + T = A->getValue(); } else { - // Use the compilation dir. - Arg *A = Args.getLastArg(options::OPT_ffile_compilation_dir_EQ, - options::OPT_fdebug_compilation_dir_EQ); - SmallString<128> T(A ? A->getValue() : ""); - SmallString<128> F(llvm::sys::path::stem(Input.getBaseInput())); - AddPostfix(F); - T += F; - return Args.MakeArgString(T); + Arg *FinalOutput = Args.getLastArg(options::OPT_o); + if (FinalOutput && Args.hasArg(options::OPT_c)) { + T = FinalOutput->getValue(); + llvm::sys::path::remove_filename(T); + llvm::sys::path::append(T, + llvm::sys::path::stem(FinalOutput->getValue())); + AddPostfix(T); + return Args.MakeArgString(T); + } } + + T += llvm::sys::path::stem(Input.getBaseInput()); + AddPostfix(T); + return Args.MakeArgString(T); } void tools::SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T, diff --git a/clang/test/Driver/hip-gsplit-dwarf-options.hip b/clang/test/Driver/hip-gsplit-dwarf-options.hip index e9f87872da869..cfd5c5020e663 100644 --- a/clang/test/Driver/hip-gsplit-dwarf-options.hip +++ b/clang/test/Driver/hip-gsplit-dwarf-options.hip @@ -13,13 +13,17 @@ // RUN: %clang -### --target=x86_64-unknown-linux-gnu \ // RUN: --offload-arch=gfx906:xnack+ %s -nogpulib -nogpuinc \ // RUN: --offload-arch=gfx900 \ -// RUN: -ggdb -gsplit-dwarf 2>&1 | FileCheck %s +// RUN: -ggdb -gsplit-dwarf 2>&1 | FileCheck %s --check-prefix=LINK // RUN: %clang -### --target=x86_64-unknown-linux-gnu \ // RUN: -fgpu-rdc --offload-arch=gfx906:xnack+ %s -nogpulib -nogpuinc \ // RUN: --offload-arch=gfx900 \ -// RUN: -ggdb -gsplit-dwarf 2>&1 | FileCheck %s +// RUN: -ggdb -gsplit-dwarf 2>&1 | FileCheck %s --check-prefix=LINK // CHECK-DAG: {{".*clang.*".* "-target-cpu" "gfx906".* "-split-dwarf-output" "hip-gsplit-dwarf-options_gfx906:xnack\+.dwo"}} // CHECK-DAG: {{".*clang.*".* "-target-cpu" "gfx900".* "-split-dwarf-output" "hip-gsplit-dwarf-options_gfx900.dwo"}} // CHECK-DAG: {{".*clang.*".* "-target-cpu" "x86-64".* "-split-dwarf-output" "hip-gsplit-dwarf-options.dwo"}} + +// LINK-DAG: {{".*clang.*".* "-target-cpu" "gfx906".* "-split-dwarf-output" "a-hip-gsplit-dwarf-options_gfx906:xnack\+.dwo"}} +// LINK-DAG: {{".*clang.*".* "-target-cpu" "gfx900".* "-split-dwarf-output" "a-hip-gsplit-dwarf-options_gfx900.dwo"}} +// LINK-DAG: {{".*clang.*".* "-target-cpu" "x86-64".* "-split-dwarf-output" "a-hip-gsplit-dwarf-options.dwo"}} diff --git a/clang/test/Driver/split-debug.c b/clang/test/Driver/split-debug.c index 94db20b554046..19214f997c669 100644 --- a/clang/test/Driver/split-debug.c +++ b/clang/test/Driver/split-debug.c @@ -9,6 +9,7 @@ // INLINE: "-fsplit-dwarf-inlining" // NOINLINE-NOT: "-fsplit-dwarf-inlining" +// SPLIT-NOT: "-dumpdir" // SPLIT: "-debug-info-kind=constructor" // SPLIT-SAME: "-ggnu-pubnames" // SPLIT-SAME: "-split-dwarf-file" "split-debug.dwo" "-split-dwarf-output" "split-debug.dwo" @@ -54,8 +55,29 @@ // SINGLE_WITH_FILENAME: "-split-dwarf-file" "{{.*}}foo.o" // SINGLE_WITH_FILENAME-NOT: "-split-dwarf-output" -/// Without -c, clang performs linking as well. The output is unchanged. -// RUN: %clang -### -target x86_64-unknown-linux-gnu -gsplit-dwarf -g %s -o ignore.d 2>&1 | FileCheck %s --check-prefix=SPLIT +/// If linking is the final phase, the .dwo filename is derived from -o (if specified) or "a". +// RUN: %clang -### --target=x86_64-unknown-linux-gnu -gsplit-dwarf -g %s -o obj/out 2>&1 | FileCheck %s --check-prefix=SPLIT_LINK +// RUN: %clang -### --target=x86_64-unknown-linux-gnu -gsplit-dwarf -g %s 2>&1 | FileCheck %s --check-prefix=SPLIT_LINK_A + +// SPLIT_LINK: "-dumpdir" "obj/out-" +// SPLIT_LINK: "-debug-info-kind=constructor" +// SPLIT_LINK-SAME: "-split-dwarf-file" "obj/out-split-debug.dwo" "-split-dwarf-output" "obj/out-split-debug.dwo" +// SPLIT_LINK_A: "-dumpdir" "a-" +// SPLIT_LINK_A-SAME: "-split-dwarf-file" "a-split-debug.dwo" "-split-dwarf-output" "a-split-debug.dwo" + +/// GCC special cases /dev/null (HOST_BIT_BUCKET) but not other special files like /dev/zero. +/// We don't apply special rules at all. +// RUN: %clang -### --target=x86_64-unknown-linux-gnu -gsplit-dwarf -g %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=SPLIT_LINK_NULL + +// SPLIT_LINK_NULL: "-dumpdir" "/dev/null-" +// SPLIT_LINK_NULL-SAME: "-split-dwarf-output" "/dev/null-split-debug.dwo" + +/// If -dumpdir is specified, use its value to derive the .dwo filename. +// RUN: %clang -### --target=x86_64-unknown-linux-gnu -gsplit-dwarf -g %s -o obj/out -dumpdir pf/x -c 2>&1 | FileCheck %s --check-prefix=DUMPDIR +// RUN: %clang -### --target=x86_64-unknown-linux-gnu -gsplit-dwarf -g %s -o obj/out -dumpdir pf/x 2>&1 | FileCheck %s --check-prefix=DUMPDIR + +// DUMPDIR: "-dumpdir" "pf/x" +// DUMPDIR-SAME: "-split-dwarf-output" "pf/xsplit-debug.dwo" /// -fsplit-dwarf-inlining // RUN: %clang -### -c -target x86_64 -gsplit-dwarf=split -g -fsplit-dwarf-inlining %s 2>&1 | FileCheck %s --check-prefixes=INLINE,SPLIT