Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -1952,6 +1952,7 @@ Flags<[CC1Option]>, HelpText<"Provide minimal debug info in the object/executable to facilitate online symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF">; def fno_split_dwarf_inlining: Flag<["-"], "fno-split-dwarf-inlining">, Group, Flags<[CC1Option]>; +def fdebug_default_version: Joined<["-"], "fdebug-default-version=">, Group; def fdebug_prefix_map_EQ : Joined<["-"], "fdebug-prefix-map=">, Group, Flags<[CC1Option,CC1AsOption]>, @@ -1998,6 +1999,7 @@ HelpText<"Emit type record hashes in a .debug$H section">, Flags<[CC1Option, CoreOption]>; def gno_codeview_ghash : Flag<["-"], "gno-codeview-ghash">, Flags<[CoreOption]>; + def ginline_line_tables : Flag<["-"], "ginline-line-tables">, Flags<[CoreOption]>; def gno_inline_line_tables : Flag<["-"], "gno-inline-line-tables">, Flags<[CC1Option, CoreOption]>, HelpText<"Don't emit inline line tables">; Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -3145,6 +3145,7 @@ // This avoids having to monkey around further in cc1 other than to disable // codeview if not running in a Windows environment. Perhaps even that // decision should be made in the driver as well though. + unsigned DefaultDWARFVersion = ParseDebugDefaultVersion(TC, Args); unsigned DWARFVersion = 0; llvm::DebuggerKind DebuggerTuning = TC.getDefaultDebuggerTuning(); @@ -3233,11 +3234,17 @@ DWARFVersion = TC.GetDefaultDwarfVersion(); assert(DWARFVersion && "toolchain default DWARF version must be nonzero"); + // If the user specified a default DWARF version, that takes precedent over + // the platform default. + if (DefaultDWARFVersion) + DWARFVersion = DefaultDWARFVersion; + // Override with a user-specified DWARF version if (GDwarfN) if (auto ExplicitVersion = DwarfVersionNum(GDwarfN->getSpelling())) DWARFVersion = ExplicitVersion; - } + } else if (DefaultDWARFVersion != 0) + DWARFVersion = DefaultDWARFVersion; // -gline-directives-only supported only for the DWARF debug info. if (DWARFVersion == 0 && DebugInfoKind == codegenoptions::DebugDirectivesOnly) @@ -6161,6 +6168,10 @@ if (WantDebug) DwarfVersion = DwarfVersionNum(A->getSpelling()); } + + if (DwarfVersion == 0) + DwarfVersion = ParseDebugDefaultVersion(getToolChain(), Args); + if (DwarfVersion == 0) DwarfVersion = getToolChain().GetDefaultDwarfVersion(); Index: clang/lib/Driver/ToolChains/CommonArgs.h =================================================================== --- clang/lib/Driver/ToolChains/CommonArgs.h +++ clang/lib/Driver/ToolChains/CommonArgs.h @@ -68,6 +68,9 @@ unsigned ParseFunctionAlignment(const ToolChain &TC, const llvm::opt::ArgList &Args); +unsigned ParseDebugDefaultVersion(const ToolChain &TC, + const llvm::opt::ArgList &Args); + void AddAssemblerKPIC(const ToolChain &ToolChain, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs); Index: clang/lib/Driver/ToolChains/CommonArgs.cpp =================================================================== --- clang/lib/Driver/ToolChains/CommonArgs.cpp +++ clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1138,6 +1138,22 @@ return Value ? llvm::Log2_32_Ceil(std::min(Value, 65536u)) : Value; } +unsigned tools::ParseDebugDefaultVersion(const ToolChain &TC, + const ArgList &Args) { + const Arg *A = Args.getLastArg(options::OPT_fdebug_default_version); + + if (!A) + return 0; + + unsigned Value = 0; + if (StringRef(A->getValue()).getAsInteger(10, Value) + || Value > 5 + || Value < 1) + TC.getDriver().Diag(diag::err_drv_invalid_int_value) + << A->getAsString(Args) << A->getValue(); + return Value; +} + void tools::AddAssemblerKPIC(const ToolChain &ToolChain, const ArgList &Args, ArgStringList &CmdArgs) { llvm::Reloc::Model RelocationModel; Index: clang/test/CodeGen/debug-default-version.c =================================================================== --- /dev/null +++ clang/test/CodeGen/debug-default-version.c @@ -0,0 +1,47 @@ +// RUN: %clang -target x86_64-linux-gnu -fdebug-default-version=4 -gdwarf-2 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER2 +// RUN: %clang -target x86_64-linux-gnu -gdwarf-3 -fdebug-default-version=4 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER3 +// RUN: %clang -target x86_64-linux-gnu -gdwarf-4 -fdebug-default-version=2 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER4 +// RUN: %clang -target x86_64-linux-gnu -gdwarf-5 -S -fdebug-default-version=2 -emit-llvm -o - %s | FileCheck %s --check-prefix=VER5 +// RUN: %clang -target x86_64-linux-gnu -fdebug-default-version=5 -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER5 +// RUN: %clang -target x86_64-linux-gnu -gdwarf -fdebug-default-version=2 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER2 +// RUN: %clang -target x86_64-linux-gnu -fdebug-default-version=4 -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=NODEBUGINFO,VER4 + +// The -isysroot is used as a hack to avoid LIT messing with the SDKROOT +// environment variable which indirecty overrides the version in the target +// triple used here. +// RUN: %clang -target x86_64-apple-macosx10.11 -g -S -emit-llvm -o - %s -isysroot %t | FileCheck %s --check-prefix=VER4 +// RUN: %clang -target x86_64-apple-darwin14 -g -S -emit-llvm -o - %s -isysroot %t | FileCheck %s --check-prefix=VER2 +// RUN: %clang -target x86_64-apple-macosx10.11 -fdebug-default-version=5 -g -S -emit-llvm -o - %s -isysroot %t | FileCheck %s --check-prefix=VER5 +// RUN: %clang -target x86_64-apple-darwin14 -g -fdebug-default-version=4 -S -emit-llvm -o - %s -isysroot %t | FileCheck %s --check-prefix=VER4 + +// RUN: %clang -target powerpc-unknown-openbsd -fdebug-default-version=4 -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER4 +// RUN: %clang -target powerpc-unknown-freebsd -g -fdebug-default-version=4 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER4 +// RUN: %clang -target i386-pc-solaris -fdebug-default-version=4 -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER4 + +// Check which debug info formats we use on Windows. By default, in an MSVC +// environment, we should use codeview. You can enable dwarf, which implicitly +// disables codeview, of you can explicitly ask for both if you don't know how +// the app will be debugged. +// RUN: %clang -target i686-pc-windows-msvc -fdebug-default-version=2 -gdwarf -S -emit-llvm -o - %s \ +// RUN: | FileCheck %s --check-prefixes=VER2,NOCODEVIEW +// Explicitly request both. +// RUN: %clang -target i686-pc-windows-msvc -fdebug-default-version=4 -gdwarf -gcodeview -S -emit-llvm -o - %s \ +// RUN: | FileCheck %s --check-prefixes=VER4,CODEVIEW + +int main (void) { + return 0; +} + +// NODEBUGINFO-NOT: !llvm.dbg.cu = !{!0} + +// NOCODEVIEW-NOT: !"CodeView" + +// VER2: !{i32 2, !"Dwarf Version", i32 2} +// VER3: !{i32 2, !"Dwarf Version", i32 3} +// VER4: !{i32 2, !"Dwarf Version", i32 4} +// VER5: !{i32 2, !"Dwarf Version", i32 5} + +// NODWARF-NOT: !"Dwarf Version" +// CODEVIEW: !{i32 2, !"CodeView", i32 1} +// NOCODEVIEW-NOT: !"CodeView" +// NODWARF-NOT: !"Dwarf Version"