diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 5eb4286cc894..c8e22d2fd216 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -810,9 +810,12 @@ def ggdb0 : Flag<["-"], "ggdb0">, Group; def ggdb1 : Flag<["-"], "ggdb1">, Group; def ggdb2 : Flag<["-"], "ggdb2">, Group; def ggdb3 : Flag<["-"], "ggdb3">, Group; -def gdwarf_2 : Flag<["-"], "gdwarf-2">, Group; -def gdwarf_3 : Flag<["-"], "gdwarf-3">, Group; -def gdwarf_4 : Flag<["-"], "gdwarf-4">, Group; +def gdwarf_2 : Flag<["-"], "gdwarf-2">, Group, + HelpText<"Generate source level debug information with dwarf version 2">, Flags<[CC1Option]>; +def gdwarf_3 : Flag<["-"], "gdwarf-3">, Group, + HelpText<"Generate source level debug information with dwarf version 3">, Flags<[CC1Option]>; +def gdwarf_4 : Flag<["-"], "gdwarf-4">, Group, + HelpText<"Generate source level debug information with dwarf version 4">, Flags<[CC1Option]>; def gfull : Flag<["-"], "gfull">, Group; def gused : Flag<["-"], "gused">, Group; def gstabs : Joined<["-"], "gstabs">, Group, Flags<[Unsupported]>; diff --git a/clang/include/clang/Frontend/CodeGenOptions.def b/clang/include/clang/Frontend/CodeGenOptions.def index b414d7554f26..4dbf4d00615e 100644 --- a/clang/include/clang/Frontend/CodeGenOptions.def +++ b/clang/include/clang/Frontend/CodeGenOptions.def @@ -135,6 +135,9 @@ VALUE_CODEGENOPT(SSPBufferSize, 32, 0) /// The kind of generated debug info. ENUM_CODEGENOPT(DebugInfo, DebugInfoKind, 2, NoDebugInfo) +/// Dwarf version. +VALUE_CODEGENOPT(DwarfVersion, 3, 0) + /// The kind of inlining to perform. ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NoInlining) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index d76fee5c8443..18c56b0dae29 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -190,6 +190,11 @@ void CodeGenModule::Release() { (Context.getLangOpts().Modules || !LinkerOptionsMetadata.empty())) { EmitModuleLinkOptions(); } + if (CodeGenOpts.DwarfVersion) + // We actually want the latest version when there are conflicts. + // We can change from Warning to Latest if such mode is supported. + getModule().addModuleFlag(llvm::Module::Warning, "Dwarf Version", + CodeGenOpts.DwarfVersion); SimplifyPersonality(); diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 373939cd933a..7f22d6ff091c 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -2489,6 +2489,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Arg *A = Args.getLastArg(options::OPT_g_Group)) { if (A->getOption().matches(options::OPT_gline_tables_only)) CmdArgs.push_back("-gline-tables-only"); + else if (A->getOption().matches(options::OPT_gdwarf_2)) + CmdArgs.push_back("-gdwarf-2"); + else if (A->getOption().matches(options::OPT_gdwarf_3)) + CmdArgs.push_back("-gdwarf-3"); + else if (A->getOption().matches(options::OPT_gdwarf_4)) + CmdArgs.push_back("-gdwarf-4"); else if (!A->getOption().matches(options::OPT_g0) && !A->getOption().matches(options::OPT_ggdb0)) CmdArgs.push_back("-g"); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 1407e105f24c..d9316ec4f0f1 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -318,7 +318,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, if (Args.hasArg(OPT_gline_tables_only)) { Opts.setDebugInfo(CodeGenOptions::DebugLineTablesOnly); - } else if (Args.hasArg(OPT_g_Flag)) { + } else if (Args.hasArg(OPT_g_Flag) || Args.hasArg(OPT_gdwarf_2) || + Args.hasArg(OPT_gdwarf_3) || Args.hasArg(OPT_gdwarf_4)) { if (Args.hasFlag(OPT_flimit_debug_info, OPT_fno_limit_debug_info, true)) Opts.setDebugInfo(CodeGenOptions::LimitedDebugInfo); else @@ -326,6 +327,15 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, } Opts.DebugColumnInfo = Args.hasArg(OPT_dwarf_column_info); Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file); + if (Args.hasArg(OPT_gdwarf_2)) + Opts.DwarfVersion = 2; + else if (Args.hasArg(OPT_gdwarf_3)) + Opts.DwarfVersion = 3; + else if (Args.hasArg(OPT_gdwarf_4)) + Opts.DwarfVersion = 4; + else if (Opts.getDebugInfo() != CodeGenOptions::NoDebugInfo) + // Default Dwarf version is 3 if we are generating debug information. + Opts.DwarfVersion = 3; Opts.DisableLLVMOpts = Args.hasArg(OPT_disable_llvm_optzns); Opts.DisableRedZone = Args.hasArg(OPT_disable_red_zone); diff --git a/clang/test/CodeGen/dwarf-version.c b/clang/test/CodeGen/dwarf-version.c new file mode 100644 index 000000000000..739f18db0a09 --- /dev/null +++ b/clang/test/CodeGen/dwarf-version.c @@ -0,0 +1,10 @@ +// RUN: %clang -target x86_64-linux-gnu -gdwarf-2 -S -emit-llvm -o - %s | FileCheck %s +// RUN: %clang -target x86_64-linux-gnu -gdwarf-3 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER3 +// RUN: %clang -target x86_64-linux-gnu -gdwarf-4 -S -emit-llvm -o - %s | FileCheck %s --check-prefix=VER4 +int main (void) { + return 0; +} + +// CHECK: metadata !{i32 2, metadata !"Dwarf Version", i32 2} +// VER3: metadata !{i32 2, metadata !"Dwarf Version", i32 3} +// VER4: metadata !{i32 2, metadata !"Dwarf Version", i32 4} diff --git a/clang/test/Driver/debug-options.c b/clang/test/Driver/debug-options.c index fec3f17c48da..981fa9088016 100644 --- a/clang/test/Driver/debug-options.c +++ b/clang/test/Driver/debug-options.c @@ -7,7 +7,7 @@ // RUN: %clang -### -c -ggdb %s 2>&1 | FileCheck -check-prefix=G %s // RUN: %clang -### -c -ggdb1 %s 2>&1 | FileCheck -check-prefix=G %s // RUN: %clang -### -c -ggdb3 %s 2>&1 | FileCheck -check-prefix=G %s -// RUN: %clang -### -c -gdwarf-2 %s 2>&1 | FileCheck -check-prefix=G %s +// RUN: %clang -### -c -gdwarf-2 %s 2>&1 | FileCheck -check-prefix=G_D2 %s // // RUN: %clang -### -c -gfoo %s 2>&1 | FileCheck -check-prefix=G_NO %s // RUN: %clang -### -c -g -g0 %s 2>&1 | FileCheck -check-prefix=G_NO %s @@ -27,6 +27,9 @@ // // G: "-cc1" // G: "-g" +// +// G_D2: "-cc1" +// G_D2: "-gdwarf-2" // // G_NO: "-cc1" // G_NO-NOT: "-g"