Index: include/clang/Driver/CC1Options.td =================================================================== --- include/clang/Driver/CC1Options.td +++ include/clang/Driver/CC1Options.td @@ -639,6 +639,8 @@ HelpText<"Assume all functions with C linkage do not unwind">; def enable_split_dwarf : Flag<["-"], "enable-split-dwarf">, HelpText<"Use split dwarf/Fission">; +def single_file_split_dwarf : Flag<["-"], "single-file-split-dwarf">, + HelpText<"Use single file split dwarf">; def fno_wchar : Flag<["-"], "fno-wchar">, HelpText<"Disable C++ builtin type wchar_t">; def fconstant_string_class : Separate<["-"], "fconstant-string-class">, Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1820,6 +1820,7 @@ def gno_strict_dwarf : Flag<["-"], "gno-strict-dwarf">, Group; def gcolumn_info : Flag<["-"], "gcolumn-info">, Group, Flags<[CoreOption]>; def gno_column_info : Flag<["-"], "gno-column-info">, Group, Flags<[CoreOption]>; +def gsingle_file_split_dwarf: Flag <["-"], "gsingle-file-split-dwarf">, Group; def gsplit_dwarf : Flag<["-"], "gsplit-dwarf">, Group; def ggnu_pubnames : Flag<["-"], "ggnu-pubnames">, Group, Flags<[CC1Option]>; def gno_gnu_pubnames : Flag<["-"], "gno-gnu-pubnames">, Group, Flags<[CC1Option]>; Index: include/clang/Frontend/CodeGenOptions.h =================================================================== --- include/clang/Frontend/CodeGenOptions.h +++ include/clang/Frontend/CodeGenOptions.h @@ -174,6 +174,10 @@ /// in the backend for setting the name in the skeleton cu. std::string SplitDwarfFile; + /// The flag shows if we want to split the debug info, but keep it + /// in the object file. + bool SingleFileSplitDwarf; + /// The name of the relocation model to use. llvm::Reloc::Model RelocationModel; Index: lib/CodeGen/BackendUtil.cpp =================================================================== --- lib/CodeGen/BackendUtil.cpp +++ lib/CodeGen/BackendUtil.cpp @@ -832,7 +832,8 @@ break; default: - if (!CodeGenOpts.SplitDwarfFile.empty()) { + if (!CodeGenOpts.SplitDwarfFile.empty() && + !CodeGenOpts.SingleFileSplitDwarf) { DwoOS = openOutputFile(CodeGenOpts.SplitDwarfFile); if (!DwoOS) return; Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -3042,6 +3042,9 @@ if (DebugInfoKind == codegenoptions::NoDebugInfo) DebugInfoKind = codegenoptions::LimitedDebugInfo; CmdArgs.push_back("-enable-split-dwarf"); + + if (Args.hasArg(options::OPT_gsingle_file_split_dwarf)) + CmdArgs.push_back("-single-file-split-dwarf"); } } @@ -3703,7 +3706,7 @@ const char *SplitDWARFOut; if (SplitDWARF) { CmdArgs.push_back("-split-dwarf-file"); - SplitDWARFOut = SplitDebugName(Args, Input); + SplitDWARFOut = SplitDebugName(Args, Input, Output); CmdArgs.push_back(SplitDWARFOut); } @@ -5634,10 +5637,11 @@ CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); - if (Args.hasArg(options::OPT_gsplit_dwarf) && + if (!Args.hasArg(options::OPT_gsingle_file_split_dwarf) && + Args.hasArg(options::OPT_gsplit_dwarf) && getToolChain().getTriple().isOSLinux()) { CmdArgs.push_back("-split-dwarf-file"); - CmdArgs.push_back(SplitDebugName(Args, Input)); + CmdArgs.push_back(SplitDebugName(Args, Input, Output)); } assert(Input.isFilename() && "Invalid input."); Index: lib/Driver/ToolChains/CommonArgs.h =================================================================== --- lib/Driver/ToolChains/CommonArgs.h +++ lib/Driver/ToolChains/CommonArgs.h @@ -59,7 +59,7 @@ const Tool &T); const char *SplitDebugName(const llvm::opt::ArgList &Args, - const InputInfo &Input); + const InputInfo &Input, const InputInfo &Output); void SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T, const JobAction &JA, const llvm::opt::ArgList &Args, Index: lib/Driver/ToolChains/CommonArgs.cpp =================================================================== --- lib/Driver/ToolChains/CommonArgs.cpp +++ lib/Driver/ToolChains/CommonArgs.cpp @@ -773,7 +773,11 @@ return false; } -const char *tools::SplitDebugName(const ArgList &Args, const InputInfo &Input) { +const char *tools::SplitDebugName(const ArgList &Args, const InputInfo &Input, + const InputInfo &Output) { + if (Args.hasArg(options::OPT_gsingle_file_split_dwarf)) + return Args.MakeArgString(Output.getFilename()); + Arg *FinalOutput = Args.getLastArg(options::OPT_o); if (FinalOutput && Args.hasArg(options::OPT_c)) { SmallString<128> T(FinalOutput->getValue()); Index: lib/Driver/ToolChains/Gnu.cpp =================================================================== --- lib/Driver/ToolChains/Gnu.cpp +++ lib/Driver/ToolChains/Gnu.cpp @@ -784,7 +784,7 @@ if (Args.hasArg(options::OPT_gsplit_dwarf) && getToolChain().getTriple().isOSLinux()) SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, - SplitDebugName(Args, Inputs[0])); + SplitDebugName(Args, Inputs[0], Output)); } namespace { Index: lib/Driver/ToolChains/MinGW.cpp =================================================================== --- lib/Driver/ToolChains/MinGW.cpp +++ lib/Driver/ToolChains/MinGW.cpp @@ -52,7 +52,7 @@ if (Args.hasArg(options::OPT_gsplit_dwarf)) SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, - SplitDebugName(Args, Inputs[0])); + SplitDebugName(Args, Inputs[0], Output)); } void tools::MinGW::Linker::AddLibGCC(const ArgList &Args, Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -597,6 +597,8 @@ Opts.EnableSplitDwarf = Args.hasArg(OPT_enable_split_dwarf); Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file); Opts.SplitDwarfInlining = !Args.hasArg(OPT_fno_split_dwarf_inlining); + Opts.SingleFileSplitDwarf = Args.hasArg(OPT_single_file_split_dwarf); + Opts.DebugTypeExtRefs = Args.hasArg(OPT_dwarf_ext_refs); Opts.DebugExplicitImport = Args.hasArg(OPT_dwarf_explicit_import); Opts.DebugFwdTemplateParams = Args.hasArg(OPT_debug_forward_template_params); Index: test/CodeGen/split-debug-single-file.c =================================================================== --- test/CodeGen/split-debug-single-file.c +++ test/CodeGen/split-debug-single-file.c @@ -0,0 +1,16 @@ +// REQUIRES: x86-registered-target + +// Testing to ensure -single-file-split-dwarf allows to place .dwo sections into regular output object. +// RUN: %clang_cc1 -debug-info-kind=limited -triple x86_64-unknown-linux \ +// RUN: -enable-split-dwarf -split-dwarf-file %t.o -emit-obj -single-file-split-dwarf -o %t.o %s +// RUN: llvm-objdump -section-headers %t.o | FileCheck --check-prefix=SINGLE-FILE-SPLIT %s +// SINGLE-FILE-SPLIT: .dwo + +// Testing to ensure that the dwo name gets output into the compile unit. +// RUN: %clang_cc1 -debug-info-kind=limited -split-dwarf-file foo.o -single-file-split-dwarf \ +// RUN: -S -emit-llvm -o - %s | FileCheck %s --check-prefix=DWONAME +// DWONAME: !DICompileUnit({{.*}}, splitDebugFilename: "foo.o" + +int main (void) { + return 0; +} Index: test/Driver/split-debug.c =================================================================== --- test/Driver/split-debug.c +++ test/Driver/split-debug.c @@ -5,6 +5,17 @@ // // CHECK-ACTIONS: "-split-dwarf-file" "split-debug.dwo" +// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf -gsingle-file-split-dwarf -c -### %s 2> %t +// RUN: FileCheck -check-prefix=CHECK-ACTIONS-SINGLE-SPLIT < %t %s +// +// CHECK-ACTIONS-SINGLE-SPLIT: "-single-file-split-dwarf" +// CHECK-ACTIONS-SINGLE-SPLIT: "-split-dwarf-file" "split-debug.o" + +// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf -gsingle-file-split-dwarf -c -### -o %tfoo.o %s 2> %t +// RUN: FileCheck -check-prefix=CHECK-SINGLE-SPLIT-FILENAME < %t %s +// +// CHECK-SINGLE-SPLIT-FILENAME: "-split-dwarf-file" "{{.*}}foo.o" + // RUN: %clang -target x86_64-macosx -gsplit-dwarf -c -### %s 2> %t // RUN: FileCheck -check-prefix=CHECK-NO-ACTIONS < %t %s Index: test/Driver/split-debug.s =================================================================== --- test/Driver/split-debug.s +++ test/Driver/split-debug.s @@ -5,6 +5,9 @@ // // CHECK-ACTIONS: "-split-dwarf-file" "split-debug.dwo" +// Check we do not pass any -split-dwarf commands to `as` if -gsingle-file-split-dwarf is specified. +// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf -gsingle-file-split-dwarf -c -### %s 2> %t +// RUN: FileCheck -check-prefix=CHECK-NO-ACTIONS < %t %s // RUN: %clang -target x86_64-macosx -gsplit-dwarf -c -### %s 2> %t // RUN: FileCheck -check-prefix=CHECK-NO-ACTIONS < %t %s