summaryrefslogtreecommitdiffstats
path: root/clang/lib/Driver
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Driver')
-rw-r--r--clang/lib/Driver/ToolChains.h13
-rw-r--r--clang/lib/Driver/Tools.cpp155
-rw-r--r--clang/lib/Driver/Tools.h5
3 files changed, 130 insertions, 43 deletions
diff --git a/clang/lib/Driver/ToolChains.h b/clang/lib/Driver/ToolChains.h
index ee571dbc0ac..a1811e9a4f2 100644
--- a/clang/lib/Driver/ToolChains.h
+++ b/clang/lib/Driver/ToolChains.h
@@ -508,6 +508,12 @@ public:
void AddLinkARCArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;
+
+ unsigned GetDefaultDwarfVersion() const override { return 2; }
+ // 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; }
+
/// }
private:
@@ -564,6 +570,8 @@ public:
const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
+ unsigned GetDefaultDwarfVersion() const override { return 2; }
+
protected:
Tool *buildAssembler() const override;
Tool *buildLinker() const override;
@@ -615,6 +623,7 @@ public:
unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const override {
return 2;
}
+ unsigned GetDefaultDwarfVersion() const override { return 2; }
protected:
Tool *buildAssembler() const override;
@@ -661,6 +670,10 @@ public:
bool UseSjLjExceptions() const override;
bool isPIEDefault() const override;
SanitizerMask getSupportedSanitizers() const override;
+ unsigned GetDefaultDwarfVersion() const override { return 2; }
+ // 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; }
protected:
Tool *buildAssembler() const override;
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index 26e767f54a6..b230b4549dd 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -2324,6 +2324,38 @@ static bool UseRelaxAll(Compilation &C, const ArgList &Args) {
RelaxDefault);
}
+// 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.
+static unsigned DwarfVersionNum(StringRef ArgValue) {
+ return llvm::StringSwitch<unsigned>(ArgValue)
+ .Case("-gdwarf-2", 2)
+ .Case("-gdwarf-3", 3)
+ .Case("-gdwarf-4", 4)
+ .Default(0);
+}
+
+static void RenderDebugEnablingArgs(const ArgList &Args, ArgStringList &CmdArgs,
+ CodeGenOptions::DebugInfoKind DebugInfoKind,
+ unsigned DwarfVersion) {
+ switch (DebugInfoKind) {
+ case CodeGenOptions::DebugLineTablesOnly:
+ CmdArgs.push_back("-debug-info-kind=line-tables-only");
+ break;
+ case CodeGenOptions::LimitedDebugInfo:
+ CmdArgs.push_back("-debug-info-kind=limited");
+ break;
+ case CodeGenOptions::FullDebugInfo:
+ CmdArgs.push_back("-debug-info-kind=standalone");
+ break;
+ default:
+ break;
+ }
+ if (DwarfVersion > 0)
+ CmdArgs.push_back(
+ Args.MakeArgString("-dwarf-version=" + std::to_string(DwarfVersion)));
+}
+
static void CollectArgsForIntegratedAssembler(Compilation &C,
const ArgList &Args,
ArgStringList &CmdArgs,
@@ -2373,7 +2405,14 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
if (Value == "-I")
TakeNextArg = true;
} else if (Value.startswith("-gdwarf-")) {
- CmdArgs.push_back(Value.data());
+ // "-gdwarf-N" options are not cc1as options.
+ unsigned DwarfVersion = DwarfVersionNum(Value);
+ if (DwarfVersion == 0) { // Send it onward, and let cc1as complain.
+ CmdArgs.push_back(Value.data());
+ } else {
+ RenderDebugEnablingArgs(
+ Args, CmdArgs, CodeGenOptions::LimitedDebugInfo, DwarfVersion);
+ }
} else if (Value.startswith("-mcpu") || Value.startswith("-mfpu") ||
Value.startswith("-mhwdiv") || Value.startswith("-march")) {
// Do nothing, we'll validate it later.
@@ -3710,9 +3749,23 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
break;
}
+ // 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:
+ // * what level of debug info to generate
+ // * what dwarf version to write
+ // 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.
+ enum CodeGenOptions::DebugInfoKind DebugInfoKind =
+ CodeGenOptions::NoDebugInfo;
+ // These two are potentially updated by AddClangCLArgs.
+ unsigned DwarfVersion = 0;
+ bool EmitCodeView = false;
+
// Add clang-cl arguments.
if (getToolChain().getDriver().IsCLMode())
- AddClangCLArgs(Args, CmdArgs);
+ AddClangCLArgs(Args, CmdArgs, &DebugInfoKind, &EmitCodeView);
// Pass the linker version in use.
if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
@@ -3753,41 +3806,41 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
: "-");
}
- // Use the last option from "-g" group. "-gline-tables-only" and "-gdwarf-x"
- // are preserved, all other debug options are substituted with "-g".
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())) {
- // FIXME: we should support specifying dwarf version with
- // -gline-tables-only.
- CmdArgs.push_back("-gline-tables-only");
- // Default is dwarf-2 for Darwin, OpenBSD, FreeBSD and Solaris.
- const llvm::Triple &Triple = getToolChain().getTriple();
- if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::OpenBSD ||
- Triple.getOS() == llvm::Triple::FreeBSD ||
- Triple.getOS() == llvm::Triple::Solaris)
- CmdArgs.push_back("-gdwarf-2");
+ DebugInfoKind = CodeGenOptions::DebugLineTablesOnly;
SplitDwarfArg = nullptr;
- } else if (A->getOption().matches(options::OPT_gdwarf_2) ||
- A->getOption().matches(options::OPT_gdwarf_3) ||
- A->getOption().matches(options::OPT_gdwarf_4)) {
- A->render(Args, CmdArgs);
} else if (!A->getOption().matches(options::OPT_g0)) {
- // Default is dwarf-2 for Darwin, OpenBSD, FreeBSD and Solaris.
- const llvm::Triple &Triple = getToolChain().getTriple();
- if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::OpenBSD ||
- Triple.getOS() == llvm::Triple::FreeBSD ||
- Triple.getOS() == llvm::Triple::Solaris)
- CmdArgs.push_back("-gdwarf-2");
- else
- CmdArgs.push_back("-g");
+ // Some 'g' group option other than one expressly disabling debug info
+ // must have been the final (winning) one. They're all equivalent.
+ 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 (Arg *A = Args.getLastArg(options::OPT_gdwarf_2, options::OPT_gdwarf_3,
+ options::OPT_gdwarf_4))
+ DwarfVersion = DwarfVersionNum(A->getSpelling());
+
// Forward -gcodeview.
- Args.AddLastArg(CmdArgs, options::OPT_gcodeview);
+ // 'EmitCodeView might have been set by CL-compatibility argument parsing.
+ if (Args.hasArg(options::OPT_gcodeview) || EmitCodeView) {
+ // DwarfVersion remains at 0 if no explicit choice was made.
+ CmdArgs.push_back("-gcodeview");
+ } else if (DwarfVersion == 0 &&
+ DebugInfoKind != CodeGenOptions::NoDebugInfo) {
+ DwarfVersion = getToolChain().GetDefaultDwarfVersion();
+ }
// We ignore flags -gstrict-dwarf and -grecord-gcc-switches for now.
Args.ClaimAllArgs(options::OPT_g_flags_Group);
@@ -3797,7 +3850,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// FIXME: Move backend command line options to the module.
if (Args.hasArg(options::OPT_gmodules)) {
- CmdArgs.push_back("-g");
+ DebugInfoKind = CodeGenOptions::LimitedDebugInfo;
CmdArgs.push_back("-dwarf-ext-refs");
CmdArgs.push_back("-fmodule-format=obj");
}
@@ -3806,11 +3859,23 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// splitting and extraction.
// FIXME: Currently only works on Linux.
if (getToolChain().getTriple().isOSLinux() && SplitDwarfArg) {
- CmdArgs.push_back("-g");
+ DebugInfoKind = CodeGenOptions::LimitedDebugInfo;
CmdArgs.push_back("-backend-option");
CmdArgs.push_back("-split-dwarf=Enable");
}
+ // After we've dealt with all combinations of things that could
+ // make DebugInfoKind be other than None or DebugLineTablesOnly,
+ // figure out if we need to "upgrade" it to standalone debug info.
+ // We parse these two '-f' options whether or not they will be used,
+ // to claim them even if you wrote "-fstandalone-debug -gline-tables-only"
+ bool NeedFullDebug = Args.hasFlag(options::OPT_fstandalone_debug,
+ options::OPT_fno_standalone_debug,
+ getToolChain().GetDefaultStandaloneDebug());
+ if (DebugInfoKind == CodeGenOptions::LimitedDebugInfo && NeedFullDebug)
+ DebugInfoKind = CodeGenOptions::FullDebugInfo;
+ RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DwarfVersion);
+
// -ggnu-pubnames turns on gnu style pubnames in the backend.
if (Args.hasArg(options::OPT_ggnu_pubnames)) {
CmdArgs.push_back("-backend-option");
@@ -4173,8 +4238,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Forward -f (flag) options which we can pass directly.
Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
- Args.AddLastArg(CmdArgs, options::OPT_fstandalone_debug);
- Args.AddLastArg(CmdArgs, options::OPT_fno_standalone_debug);
Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names);
// Emulated TLS is enabled by default on Android, and can be enabled manually
// with -femulated-tls.
@@ -5336,7 +5399,9 @@ static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args) {
return EH;
}
-void Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
+void Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs,
+ enum CodeGenOptions::DebugInfoKind *DebugInfoKind,
+ bool *EmitCodeView) const {
unsigned RTOptionID = options::OPT__SLASH_MT;
if (Args.hasArg(options::OPT__SLASH_LDd))
@@ -5400,13 +5465,13 @@ void Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
CmdArgs.push_back("-fno-rtti-data");
// Emit CodeView if -Z7 is present.
- bool EmitCodeView = Args.hasArg(options::OPT__SLASH_Z7);
+ *EmitCodeView = Args.hasArg(options::OPT__SLASH_Z7);
bool EmitDwarf = Args.hasArg(options::OPT_gdwarf);
// If we are emitting CV but not DWARF, don't build information that LLVM
// can't yet process.
- if (EmitCodeView && !EmitDwarf)
- CmdArgs.push_back("-gline-tables-only");
- if (EmitCodeView)
+ if (*EmitCodeView && !EmitDwarf)
+ *DebugInfoKind = CodeGenOptions::DebugLineTablesOnly;
+ if (*EmitCodeView)
CmdArgs.push_back("-gcodeview");
const Driver &D = getToolChain().getDriver();
@@ -5557,14 +5622,20 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
// with an actual assembly file.
if (SourceAction->getType() == types::TY_Asm ||
SourceAction->getType() == types::TY_PP_Asm) {
+ bool WantDebug = false;
+ unsigned DwarfVersion = 0;
Args.ClaimAllArgs(options::OPT_g_Group);
- if (Arg *A = Args.getLastArg(options::OPT_g_Group))
- if (!A->getOption().matches(options::OPT_g0))
- CmdArgs.push_back("-g");
-
- if (Arg *A = Args.getLastArg(options::OPT_gdwarf_2, options::OPT_gdwarf_3,
- options::OPT_gdwarf_4))
- A->render(Args, CmdArgs);
+ if (Arg *A = Args.getLastArg(options::OPT_g_Group)) {
+ WantDebug = !A->getOption().matches(options::OPT_g0);
+ if (WantDebug) {
+ if ((DwarfVersion = DwarfVersionNum(A->getSpelling())) == 0)
+ DwarfVersion = getToolChain().GetDefaultDwarfVersion();
+ }
+ }
+ RenderDebugEnablingArgs(Args, CmdArgs,
+ (WantDebug ? CodeGenOptions::LimitedDebugInfo
+ : CodeGenOptions::NoDebugInfo),
+ DwarfVersion);
// Add the -fdebug-compilation-dir flag if needed.
addDebugCompDirArg(Args, CmdArgs);
diff --git a/clang/lib/Driver/Tools.h b/clang/lib/Driver/Tools.h
index 30ddcc90c23..bc10171d52c 100644
--- a/clang/lib/Driver/Tools.h
+++ b/clang/lib/Driver/Tools.h
@@ -14,6 +14,7 @@
#include "clang/Driver/Tool.h"
#include "clang/Driver/Types.h"
#include "clang/Driver/Util.h"
+#include "clang/Frontend/CodeGenOptions.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/Compiler.h"
@@ -88,7 +89,9 @@ private:
RewriteKind rewrite) const;
void AddClangCLArgs(const llvm::opt::ArgList &Args,
- llvm::opt::ArgStringList &CmdArgs) const;
+ llvm::opt::ArgStringList &CmdArgs,
+ enum CodeGenOptions::DebugInfoKind *DebugInfoKind,
+ bool *EmitCodeView) const;
visualstudio::Compiler *getCLFallback() const;
OpenPOWER on IntegriCloud