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 fdwarf_default_version: Joined<["-"], "fdwarf-default-version=">, Group; def fdebug_prefix_map_EQ : Joined<["-"], "fdebug-prefix-map=">, Group, Flags<[CC1Option,CC1AsOption]>, Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -3145,7 +3145,6 @@ // 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 DWARFVersion = 0; llvm::DebuggerKind DebuggerTuning = TC.getDefaultDebuggerTuning(); bool SplitDWARFInlining = @@ -3228,11 +3227,18 @@ } } + unsigned DWARFVersion = 0; + unsigned DefaultDWARFVersion = ParseDwarfDefaultVersion(TC, Args); if (EmitDwarf) { // Start with the platform default DWARF version DWARFVersion = TC.GetDefaultDwarfVersion(); assert(DWARFVersion && "toolchain default DWARF version must be nonzero"); + // If the user specified a default DWARF version, that takes precedence + // over the platform default. + if (DefaultDWARFVersion) + DWARFVersion = DefaultDWARFVersion; + // Override with a user-specified DWARF version if (GDwarfN) if (auto ExplicitVersion = DwarfVersionNum(GDwarfN->getSpelling())) @@ -6161,6 +6167,10 @@ if (WantDebug) DwarfVersion = DwarfVersionNum(A->getSpelling()); } + + if (DwarfVersion == 0) + DwarfVersion = ParseDwarfDefaultVersion(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 ParseDwarfDefaultVersion(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::ParseDwarfDefaultVersion(const ToolChain &TC, + const ArgList &Args) { + const Arg *A = Args.getLastArg(options::OPT_fdwarf_default_version); + + if (!A) + return 0; + + unsigned Value = 0; + if (StringRef(A->getValue()).getAsInteger(10, Value) + || Value > 5 + || Value < 2) + 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/Driver/dwarf-default-version.c =================================================================== --- /dev/null +++ clang/test/Driver/dwarf-default-version.c @@ -0,0 +1,47 @@ +// RUN: %clang -target x86_64-linux-gnu -fdwarf-default-version=4 -gdwarf-2 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=DWARF2 +// RUN: %clang -target x86_64-linux-gnu -gdwarf-3 -fdwarf-default-version=4 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=DWARF3 +// RUN: %clang -target x86_64-linux-gnu -gdwarf-4 -fdwarf-default-version=2 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=DWARF4 +// RUN: %clang -target x86_64-linux-gnu -gdwarf-5 -S -fdwarf-default-version=2 -emit-llvm -o - %s | FileCheck %s --check-prefix=DWARF5 +// RUN: %clang -target x86_64-linux-gnu -fdwarf-default-version=5 -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=DWARF5 +// RUN: %clang -target x86_64-linux-gnu -gdwarf -fdwarf-default-version=2 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=DWARF2 +// RUN: %clang -target x86_64-linux-gnu -fdwarf-default-version=4 -S -emit-llvm -o - %s | FileCheck %s --check-prefixes=NODEBUGINFO,NODWARF + +// 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=DWARF4 +// RUN: %clang -target x86_64-apple-darwin14 -g -S -emit-llvm -o - %s -isysroot %t | FileCheck %s --check-prefix=DWARF2 +// RUN: %clang -target x86_64-apple-macosx10.11 -fdwarf-default-version=5 -g -S -emit-llvm -o - %s -isysroot %t | FileCheck %s --check-prefix=DWARF5 +// RUN: %clang -target x86_64-apple-darwin14 -g -fdwarf-default-version=4 -S -emit-llvm -o - %s -isysroot %t | FileCheck %s --check-prefix=DWARF4 + +// RUN: %clang -target powerpc-unknown-openbsd -fdwarf-default-version=4 -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=DWARF4 +// RUN: %clang -target powerpc-unknown-freebsd -g -fdwarf-default-version=4 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=DWARF4 +// RUN: %clang -target i386-pc-solaris -fdwarf-default-version=4 -g -S -emit-llvm -o - %s | FileCheck %s --check-prefix=DWARF4 + +// 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 -fdwarf-default-version=2 -gdwarf -S -emit-llvm -o - %s \ +// RUN: | FileCheck %s --check-prefixes=DWARF2,NOCODEVIEW +// Explicitly request both. +// RUN: %clang -target i686-pc-windows-msvc -fdwarf-default-version=4 -gdwarf -gcodeview -S -emit-llvm -o - %s \ +// RUN: | FileCheck %s --check-prefixes=DWARF4,CODEVIEW + +int main (void) { + return 0; +} + +// NODEBUGINFO-NOT: !llvm.dbg.cu = !{!0} + +// NOCODEVIEW-NOT: !"CodeView" + +// DWARF2: !{i32 2, !"Dwarf Version", i32 2} +// DWARF3: !{i32 2, !"Dwarf Version", i32 3} +// DWARF4: !{i32 2, !"Dwarf Version", i32 4} +// DWARF5: !{i32 2, !"Dwarf Version", i32 5} + +// NODWARF-NOT: !"Dwarf Version" +// CODEVIEW: !{i32 2, !"CodeView", i32 1} +// NOCODEVIEW-NOT: !"CodeView" +// NODWARF-NOT: !"Dwarf Version"