Driver part of debugger tuning.

Adds driver options named -glldb and -gsce to mean -g plus tuning for
lldb and SCE debuggers respectively; the existing -ggdb option does
the same for gdb. Existing options -ggdb0, -ggdb1 etc. unpack into
-ggdb -g<N>.  (There will not be -glldb<N> or -gsce<N> options.) The
tuning gets a target-specific default in the driver, and is passed
into cc1 with the new -debugger-tuning option.

As fallout, fixes where '-gsplit-dwarf -g0' would ignore the -g0 part
on Linux.

Differential Revision: http://reviews.llvm.org/D15651

llvm-svn: 256104
This commit is contained in:
Paul Robinson 2015-12-19 19:41:48 +00:00
parent f48a1f54dd
commit 0334a047df
7 changed files with 153 additions and 42 deletions

View File

@ -1514,8 +1514,11 @@ In these cases, you can use the flag ``-fno-profile-instr-generate`` (or
Note that these flags should appear after the corresponding profile
flags to have an effect.
Controlling Debug Information
-----------------------------
Controlling Size of Debug Information
-------------------------------------
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Debug info kind generated by Clang can be set by one of the flags listed
below. If multiple flags are present, the last one is used.
@ -1559,6 +1562,21 @@ below. If multiple flags are present, the last one is used.
Generate complete debug info.
Controlling Debugger "Tuning"
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
While Clang generally emits standard DWARF debug info (http://dwarfstd.org),
different debuggers may know how to take advantage of different specific DWARF
features. You can "tune" the debug info for one of several different debuggers.
.. option:: -ggdb, -glldb, -gsce
Tune the debug info for the ``gdb``, ``lldb``, or Sony Computer Entertainment
debugger, respectively. Each of these options implies **-g**. (Therefore, if
you want both **-gline-tables-only** and debugger tuning, the tuning option
must come first.)
Comment Parsing Options
-----------------------

View File

@ -71,6 +71,9 @@ def d_Group : OptionGroup<"<d group>">;
def f_Group : OptionGroup<"<f group>">, Group<CompileOnly_Group>;
def f_clang_Group : OptionGroup<"<f (clang-only) group>">, Group<CompileOnly_Group>;
def g_Group : OptionGroup<"<g group>">;
def gN_Group : OptionGroup<"<gN group>">, Group<g_Group>;
def ggdbN_Group : OptionGroup<"<ggdbN group>">, Group<gN_Group>;
def gTune_Group : OptionGroup<"<gTune group>">, Group<g_Group>;
def g_flags_Group : OptionGroup<"<g flags group>">;
def i_Group : OptionGroup<"<i group>">, Group<CompileOnly_Group>;
def clang_i_Group : OptionGroup<"<clang i group>">, Group<i_Group>;
@ -1130,20 +1133,20 @@ def fdebug_prefix_map_EQ
HelpText<"remap file source paths in debug info">;
def g_Flag : Flag<["-"], "g">, Group<g_Group>,
HelpText<"Generate source-level debug information">;
def gline_tables_only : Flag<["-"], "gline-tables-only">, Group<g_Group>,
def gline_tables_only : Flag<["-"], "gline-tables-only">, Group<gN_Group>,
HelpText<"Emit debug line number tables only">;
def gmlt : Flag<["-"], "gmlt">, Alias<gline_tables_only>;
def g0 : Flag<["-"], "g0">, Group<g_Group>;
def g1 : Flag<["-"], "g1">, Group<g_Group>, Alias<gline_tables_only>;
def g2 : Flag<["-"], "g2">, Group<g_Group>;
def g3 : Flag<["-"], "g3">, Group<g_Group>;
def ggdb : Flag<["-"], "ggdb">, Group<g_Group>;
def ggdb0 : Flag<["-"], "ggdb0">, Alias<g0>;
// Redirect ggdb1 to <gline_tables_only>, not <g1>,
// because aliases of aliases aren't allowed.
def ggdb1 : Flag<["-"], "ggdb1">, Alias<gline_tables_only>;
def ggdb2 : Flag<["-"], "ggdb2">, Alias<g2>;
def ggdb3 : Flag<["-"], "ggdb3">, Alias<g3>;
def g0 : Flag<["-"], "g0">, Group<gN_Group>;
def g1 : Flag<["-"], "g1">, Group<gN_Group>, Alias<gline_tables_only>;
def g2 : Flag<["-"], "g2">, Group<gN_Group>;
def g3 : Flag<["-"], "g3">, Group<gN_Group>;
def ggdb : Flag<["-"], "ggdb">, Group<gTune_Group>;
def ggdb0 : Flag<["-"], "ggdb0">, Group<ggdbN_Group>;
def ggdb1 : Flag<["-"], "ggdb1">, Group<ggdbN_Group>;
def ggdb2 : Flag<["-"], "ggdb2">, Group<ggdbN_Group>;
def ggdb3 : Flag<["-"], "ggdb3">, Group<ggdbN_Group>;
def glldb : Flag<["-"], "glldb">, Group<gTune_Group>;
def gsce : Flag<["-"], "gsce">, Group<gTune_Group>;
def gdwarf_2 : Flag<["-"], "gdwarf-2">, Group<g_Group>,
HelpText<"Generate source-level debug information with dwarf version 2">;
def gdwarf_3 : Flag<["-"], "gdwarf-3">, Group<g_Group>,

View File

@ -18,6 +18,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/Path.h"
#include "llvm/Target/TargetOptions.h"
#include <memory>
#include <string>
@ -304,6 +305,11 @@ public:
// i.e. a value of 'true' does not imply that debugging is wanted.
virtual bool GetDefaultStandaloneDebug() const { return false; }
// Return the default debugger "tuning."
virtual llvm::DebuggerKind getDefaultDebuggerTuning() const {
return llvm::DebuggerKind::GDB;
}
/// UseSjLjExceptions - Does this tool chain use SjLj exceptions.
virtual bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const {
return false;

View File

@ -566,6 +566,9 @@ public:
// Until dtrace (via CTF) and LLDB can deal with distributed debug info,
// Darwin defaults to standalone/full debug info.
bool GetDefaultStandaloneDebug() const override { return true; }
llvm::DebuggerKind getDefaultDebuggerTuning() const override {
return llvm::DebuggerKind::LLDB;
}
/// }
@ -727,6 +730,9 @@ public:
// Until dtrace (via CTF) and LLDB can deal with distributed debug info,
// FreeBSD defaults to standalone/full debug info.
bool GetDefaultStandaloneDebug() const override { return true; }
llvm::DebuggerKind getDefaultDebuggerTuning() const override {
return llvm::DebuggerKind::LLDB;
}
protected:
Tool *buildAssembler() const override;
@ -1122,6 +1128,10 @@ public:
return 2; // SSPStrong
}
llvm::DebuggerKind getDefaultDebuggerTuning() const override {
return llvm::DebuggerKind::SCE;
}
SanitizerMask getSupportedSanitizers() const override;
protected:

View File

@ -2487,6 +2487,20 @@ static bool UseRelaxAll(Compilation &C, const ArgList &Args) {
RelaxDefault);
}
// Convert an arg of the form "-gN" or "-ggdbN" or one of their aliases
// to the corresponding DebugInfoKind.
static CodeGenOptions::DebugInfoKind DebugLevelToInfoKind(const Arg &A) {
assert(A.getOption().matches(options::OPT_gN_Group) &&
"Not a -g option that specifies a debug-info level");
if (A.getOption().matches(options::OPT_g0) ||
A.getOption().matches(options::OPT_ggdb0))
return CodeGenOptions::NoDebugInfo;
if (A.getOption().matches(options::OPT_gline_tables_only) ||
A.getOption().matches(options::OPT_ggdb1))
return CodeGenOptions::DebugLineTablesOnly;
return CodeGenOptions::LimitedDebugInfo;
}
// Extract the integer N from a string spelled "-dwarf-N", returning 0
// on mismatch. The StringRef input (rather than an Arg) allows
// for use by the "-Xassembler" option parser.
@ -2500,7 +2514,8 @@ static unsigned DwarfVersionNum(StringRef ArgValue) {
static void RenderDebugEnablingArgs(const ArgList &Args, ArgStringList &CmdArgs,
CodeGenOptions::DebugInfoKind DebugInfoKind,
unsigned DwarfVersion) {
unsigned DwarfVersion,
llvm::DebuggerKind DebuggerTuning) {
switch (DebugInfoKind) {
case CodeGenOptions::DebugLineTablesOnly:
CmdArgs.push_back("-debug-info-kind=line-tables-only");
@ -2517,6 +2532,19 @@ static void RenderDebugEnablingArgs(const ArgList &Args, ArgStringList &CmdArgs,
if (DwarfVersion > 0)
CmdArgs.push_back(
Args.MakeArgString("-dwarf-version=" + Twine(DwarfVersion)));
switch (DebuggerTuning) {
case llvm::DebuggerKind::GDB:
CmdArgs.push_back("-debugger-tuning=gdb");
break;
case llvm::DebuggerKind::LLDB:
CmdArgs.push_back("-debugger-tuning=lldb");
break;
case llvm::DebuggerKind::SCE:
CmdArgs.push_back("-debugger-tuning=sce");
break;
default:
break;
}
}
static void CollectArgsForIntegratedAssembler(Compilation &C,
@ -2604,7 +2632,8 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
CmdArgs.push_back(Value.data());
} else {
RenderDebugEnablingArgs(
Args, CmdArgs, CodeGenOptions::LimitedDebugInfo, DwarfVersion);
Args, CmdArgs, CodeGenOptions::LimitedDebugInfo, DwarfVersion,
llvm::DebuggerKind::Default);
}
} else if (Value.startswith("-mcpu") || Value.startswith("-mfpu") ||
Value.startswith("-mhwdiv") || Value.startswith("-march")) {
@ -3977,16 +4006,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// The 'g' groups options involve a somewhat intricate sequence of decisions
// about what to pass from the driver to the frontend, but by the time they
// reach cc1 they've been factored into two well-defined orthogonal choices:
// reach cc1 they've been factored into three well-defined orthogonal choices:
// * what level of debug info to generate
// * what dwarf version to write
// * what debugger tuning to use
// 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 = getToolChain().getDefaultDebuggerTuning();
// These two are potentially updated by AddClangCLArgs.
enum CodeGenOptions::DebugInfoKind DebugInfoKind =
CodeGenOptions::NoDebugInfo;
// These two are potentially updated by AddClangCLArgs.
unsigned DwarfVersion = 0;
bool EmitCodeView = false;
// Add clang-cl arguments.
@ -4035,25 +4066,32 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.ClaimAllArgs(options::OPT_g_Group);
Arg *SplitDwarfArg = Args.getLastArg(options::OPT_gsplit_dwarf);
if (Arg *A = Args.getLastArg(options::OPT_g_Group)) {
// If you say "-gline-tables-only -gsplit-dwarf", split-dwarf wins,
// which mandates turning on "-g". But -split-dwarf is not a g_group option,
// hence it takes a nontrivial test to decide about line-tables-only.
if (A->getOption().matches(options::OPT_gline_tables_only) &&
(!SplitDwarfArg || A->getIndex() > SplitDwarfArg->getIndex())) {
DebugInfoKind = CodeGenOptions::DebugLineTablesOnly;
SplitDwarfArg = nullptr;
} else if (!A->getOption().matches(options::OPT_g0)) {
// Some 'g' group option other than one expressly disabling debug info
// must have been the final (winning) one. They're all equivalent.
// If the last option explicitly specified a debug-info level, use it.
if (A->getOption().matches(options::OPT_gN_Group)) {
DebugInfoKind = DebugLevelToInfoKind(*A);
// If you say "-gsplit-dwarf -gline-tables-only", -gsplit-dwarf loses.
// But -gsplit-dwarf is not a g_group option, hence we have to check the
// order explicitly. (If -gsplit-dwarf wins, we fix DebugInfoKind later.)
if (SplitDwarfArg && DebugInfoKind < CodeGenOptions::LimitedDebugInfo &&
A->getIndex() > SplitDwarfArg->getIndex())
SplitDwarfArg = nullptr;
} else
// For any other 'g' option, use Limited.
DebugInfoKind = CodeGenOptions::LimitedDebugInfo;
}
}
// If a -gdwarf argument appeared, use it, unless DebugInfoKind is None
// (because that would mean that "-g0" was the rightmost 'g' group option).
// FIXME: specifying "-gdwarf-<N>" "-g1" in that order works,
// but "-g1" "-gdwarf-<N>" does not. A deceptively simple (but wrong) "fix"
// exists of removing the gdwarf options from the g_group.
// If a debugger tuning argument appeared, remember it.
if (Arg *A = Args.getLastArg(options::OPT_gTune_Group,
options::OPT_ggdbN_Group)) {
if (A->getOption().matches(options::OPT_glldb))
DebuggerTuning = llvm::DebuggerKind::LLDB;
else if (A->getOption().matches(options::OPT_gsce))
DebuggerTuning = llvm::DebuggerKind::SCE;
else
DebuggerTuning = llvm::DebuggerKind::GDB;
}
// If a -gdwarf argument appeared, remember it.
if (Arg *A = Args.getLastArg(options::OPT_gdwarf_2, options::OPT_gdwarf_3,
options::OPT_gdwarf_4))
DwarfVersion = DwarfVersionNum(A->getSpelling());
@ -4102,7 +4140,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
getToolChain().GetDefaultStandaloneDebug());
if (DebugInfoKind == CodeGenOptions::LimitedDebugInfo && NeedFullDebug)
DebugInfoKind = CodeGenOptions::FullDebugInfo;
RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DwarfVersion);
RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DwarfVersion,
DebuggerTuning);
// -ggnu-pubnames turns on gnu style pubnames in the backend.
if (Args.hasArg(options::OPT_ggnu_pubnames)) {
@ -5888,7 +5927,8 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
unsigned DwarfVersion = 0;
Args.ClaimAllArgs(options::OPT_g_Group);
if (Arg *A = Args.getLastArg(options::OPT_g_Group)) {
WantDebug = !A->getOption().matches(options::OPT_g0);
WantDebug = !A->getOption().matches(options::OPT_g0) &&
!A->getOption().matches(options::OPT_ggdb0);
if (WantDebug)
DwarfVersion = DwarfVersionNum(A->getSpelling());
}
@ -5897,7 +5937,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
RenderDebugEnablingArgs(Args, CmdArgs,
(WantDebug ? CodeGenOptions::LimitedDebugInfo
: CodeGenOptions::NoDebugInfo),
DwarfVersion);
DwarfVersion, llvm::DebuggerKind::Default);
// Add the -fdebug-compilation-dir flag if needed.
addDebugCompDirArg(Args, CmdArgs);

View File

@ -2,31 +2,38 @@
// rdar://10383444
// RUN: %clang -### -c -g %s -target x86_64-linux-gnu 2>&1 \
// RUN: | FileCheck -check-prefix=G %s
// RUN: | FileCheck -check-prefix=G -check-prefix=G_GDB %s
// RUN: %clang -### -c -g2 %s -target x86_64-linux-gnu 2>&1 \
// RUN: | FileCheck -check-prefix=G %s
// RUN: %clang -### -c -g3 %s -target x86_64-linux-gnu 2>&1 \
// RUN: | FileCheck -check-prefix=G %s
// RUN: %clang -### -c -ggdb %s -target x86_64-linux-gnu 2>&1 \
// RUN: | FileCheck -check-prefix=G %s
// RUN: | FileCheck -check-prefix=G -check-prefix=G_GDB %s
// RUN: %clang -### -c -ggdb1 %s -target x86_64-linux-gnu 2>&1 \
// RUN: | FileCheck -check-prefix=GLTO_ONLY %s
// RUN: | FileCheck -check-prefix=GLTO_ONLY -check-prefix=G_GDB %s
// RUN: %clang -### -c -ggdb3 %s -target x86_64-linux-gnu 2>&1 \
// RUN: | FileCheck -check-prefix=G %s
// RUN: %clang -### -c -glldb %s -target x86_64-linux-gnu 2>&1 \
// RUN: | FileCheck -check-prefix=G -check-prefix=G_LLDB %s
// RUN: %clang -### -c -gsce %s -target x86_64-linux-gnu 2>&1 \
// RUN: | FileCheck -check-prefix=G -check-prefix=G_SCE %s
// RUN: %clang -### -c -g %s -target x86_64-apple-darwin 2>&1 \
// RUN: | FileCheck -check-prefix=G_DARWIN %s
// RUN: | FileCheck -check-prefix=G_DARWIN -check-prefix=G_LLDB %s
// RUN: %clang -### -c -g2 %s -target x86_64-apple-darwin 2>&1 \
// RUN: | FileCheck -check-prefix=G_DARWIN %s
// RUN: %clang -### -c -g3 %s -target x86_64-apple-darwin 2>&1 \
// RUN: | FileCheck -check-prefix=G_DARWIN %s
// RUN: %clang -### -c -ggdb %s -target x86_64-apple-darwin 2>&1 \
// RUN: | FileCheck -check-prefix=G_DARWIN %s
// RUN: | FileCheck -check-prefix=G_DARWIN -check-prefix=G_GDB %s
// RUN: %clang -### -c -ggdb1 %s -target x86_64-apple-darwin 2>&1 \
// RUN: | FileCheck -check-prefix=GLTO_ONLY_DWARF2 %s
// RUN: %clang -### -c -ggdb3 %s -target x86_64-apple-darwin 2>&1 \
// RUN: | FileCheck -check-prefix=G_DARWIN %s
// RUN: %clang -### -c -g %s -target x86_64-pc-freebsd10.0 2>&1 \
// RUN: | FileCheck -check-prefix=G_LLDB %s
// On the PS4, -g defaults to -gno-column-info, and we always generate the
// arange section.
// RUN: %clang -### -c %s -target x86_64-scei-ps4 2>&1 \
@ -34,6 +41,8 @@
// RUN: %clang -### -c %s -g -target x86_64-scei-ps4 2>&1 \
// RUN: | FileCheck -check-prefix=G_PS4 %s
// RUN: %clang -### -c %s -g -target x86_64-scei-ps4 2>&1 \
// RUN: | FileCheck -check-prefix=G_SCE %s
// RUN: %clang -### -c %s -g -target x86_64-scei-ps4 2>&1 \
// RUN: | FileCheck -check-prefix=NOCI %s
// RUN: %clang -### -c %s -g -gcolumn-info -target x86_64-scei-ps4 2>&1 \
// RUN: | FileCheck -check-prefix=CI %s
@ -43,6 +52,14 @@
// 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
// RUN: %clang -### -c -ggdb0 %s 2>&1 | FileCheck -check-prefix=G_NO %s
// RUN: %clang -### -c -glldb -g0 %s 2>&1 | FileCheck -check-prefix=G_NO %s
// RUN: %clang -### -c -glldb -g1 %s 2>&1 \
// RUN: | FileCheck -check-prefix=GLTO_ONLY -check-prefix=G_LLDB %s
//
// PS4 defaults to sce; -ggdb0 changes tuning but turns off debug info,
// then -g turns it back on without affecting tuning.
// RUN: %clang -### -c -ggdb0 -g -target x86_64-scei-ps4 %s 2>&1 \
// RUN: | FileCheck -check-prefix=G -check-prefix=G_GDB %s
//
// RUN: %clang -### -c -g1 %s 2>&1 \
// RUN: | FileCheck -check-prefix=GLTO_ONLY %s
@ -123,6 +140,10 @@
// G_ONLY: "-cc1"
// G_ONLY: "-debug-info-kind=limited"
//
// G_GDB: "-debugger-tuning=gdb"
// G_LLDB: "-debugger-tuning=lldb"
// G_SCE: "-debugger-tuning=sce"
//
// These tests assert that "-gline-tables-only" "-g" uses the latter,
// but otherwise not caring about the DebugInfoKind.
// G_ONLY_DWARF2: "-cc1"

View File

@ -45,3 +45,16 @@
//
// CHECK-SPLIT-OVER-GMLT: "-split-dwarf=Enable" "-debug-info-kind=limited"
// CHECK-SPLIT-OVER-GMLT: "-split-dwarf-file"
// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf -g0 -S -### %s 2> %t
// RUN: FileCheck -check-prefix=CHECK-G0-OVER-SPLIT < %t %s
//
// CHECK-G0-OVER-SPLIT-NOT: "-debug-info-kind
// CHECK-G0-OVER-SPLIT-NOT: "-split-dwarf=Enable"
// CHECK-G0-OVER-SPLIT-NOT: "-split-dwarf-file"
// RUN: %clang -target x86_64-unknown-linux-gnu -g0 -gsplit-dwarf -S -### %s 2> %t
// RUN: FileCheck -check-prefix=CHECK-SPLIT-OVER-G0 < %t %s
//
// CHECK-SPLIT-OVER-G0: "-split-dwarf=Enable" "-debug-info-kind=limited"
// CHECK-SPLIT-OVER-G0: "-split-dwarf-file"