nickdesaulniers created this revision. nickdesaulniers added reviewers: MaskRay, probinson. Herald added a subscriber: StephenFan. Herald added a project: All. nickdesaulniers requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
We've been working around this for a long time in the Linux kernel; we bend over backwards to continue to support CC=clang (w/ -fno-integrated-as) for architectures where clang can't yet be used to assemble the kernel's assembler sources. Supporting debug info for the combination of CC=clang w/ GNU binutils as "GAS" has been painful. Fix this in clang so that we can work towards dropping complexity in the Linux kernel's build system, Kbuild, for supporting this combination of tools. GAS added support for -gdwarf-{3|4|5} in 2020 2.35 release via commit 31bf18645d98 ("Add support for --dwarf-[3|4|5] to assembler command line.") Refactor code to share logic between integrated-as and non-integrated-as for determining the implicit default. This change will now always explicitly pass a -gdwarf-* flag to the GNU assembler when -g is specified. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D136707 Files: clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Driver/ToolChains/CommonArgs.cpp clang/lib/Driver/ToolChains/CommonArgs.h clang/lib/Driver/ToolChains/Gnu.cpp clang/test/Driver/as-options.s
Index: clang/test/Driver/as-options.s =================================================================== --- clang/test/Driver/as-options.s +++ clang/test/Driver/as-options.s @@ -122,7 +122,33 @@ // RUN: FileCheck --check-prefix=DEBUG %s // RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -g0 -g %s -### 2>&1 | \ // RUN: FileCheck --check-prefix=DEBUG %s -// DEBUG: "-g" +// DEBUG: "-g" "-gdwarf-5" // RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -g -g0 %s -### 2>&1 | \ // RUN: FileCheck --check-prefix=NODEBUG %s +// RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -gdwarf-5 -g0 %s -### 2>&1 | \ +// RUN: FileCheck --check-prefix=NODEBUG %s // NODEBUG-NOT: "-g" +// NODEBUG-NOT: "-gdwarf- + +// Test that -gdwarf-* is passed through to GAS. +// TODO: test without -g +// RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -gdwarf-5 %s -### 2>&1 | \ +// RUN: FileCheck --check-prefix=GDWARF5 %s +// RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -gdwarf-4 %s -### 2>&1 | \ +// RUN: FileCheck --check-prefix=GDWARF4 %s +// RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -gdwarf-3 %s -### 2>&1 | \ +// RUN: FileCheck --check-prefix=GDWARF3 %s +// RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -gdwarf-2 %s -### 2>&1 | \ +// RUN: FileCheck --check-prefix=GDWARF2 %s +// RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -gdwarf %s -### 2>&1 | \ +// RUN: FileCheck --check-prefix=GDWARF5 %s + +// RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -gdwarf-5 %s -### 2>&1 | \ +// RUN: FileCheck --check-prefix=GDWARF5 %s +// RUN: %clang --target=aarch64-linux-gnu -fno-integrated-as -g \ +// RUN: -fdebug-default-version=2 %s -### 2>&1 | FileCheck --check-prefix=GDWARF2 %s + +// GDWARF5: "-gdwarf-5" +// GDWARF4: "-gdwarf-4" +// GDWARF3: "-gdwarf-3" +// GDWARF2: "-gdwarf-2" Index: clang/lib/Driver/ToolChains/Gnu.cpp =================================================================== --- clang/lib/Driver/ToolChains/Gnu.cpp +++ clang/lib/Driver/ToolChains/Gnu.cpp @@ -969,10 +969,17 @@ for (const auto &II : Inputs) CmdArgs.push_back(II.getFilename()); - if (Arg *A = Args.getLastArg(options::OPT_g_Flag, options::OPT_gN_Group)) - if (!A->getOption().matches(options::OPT_g0)) + if (Arg *A = Args.getLastArg(options::OPT_g_Flag, options::OPT_gN_Group, + options::OPT_gdwarf_2, options::OPT_gdwarf_3, options::OPT_gdwarf_4, + options::OPT_gdwarf_5, options::OPT_gdwarf)) + if (!A->getOption().matches(options::OPT_g0)) { Args.AddLastArg(CmdArgs, options::OPT_g_Flag); + unsigned DwarfVersion = GetDwarfVersion(getToolChain(), Args); + std::string DV = "-gdwarf-" + std::to_string(DwarfVersion); + CmdArgs.push_back(Args.MakeArgString(DV)); + } + const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath(DefaultAssembler)); C.addCommand(std::make_unique<Command>(JA, *this, Index: clang/lib/Driver/ToolChains/CommonArgs.h =================================================================== --- clang/lib/Driver/ToolChains/CommonArgs.h +++ clang/lib/Driver/ToolChains/CommonArgs.h @@ -14,6 +14,9 @@ #include "clang/Driver/Multilib.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Option/Arg.h" +#include "llvm/Option/ArgList.h" #include "llvm/Support/CodeGen.h" namespace clang { @@ -103,6 +106,14 @@ unsigned ParseDebugDefaultVersion(const ToolChain &TC, const llvm::opt::ArgList &Args); +// 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. +unsigned DwarfVersionNum(StringRef ArgValue); +// Find a DWARF format version option. +// This function is a complementary for DwarfVersionNum(). +const llvm::opt::Arg *getDwarfNArg(const llvm::opt::ArgList &Args); +unsigned GetDwarfVersion(const ToolChain &TC, const llvm::opt::ArgList &Args); void AddAssemblerKPIC(const ToolChain &ToolChain, const llvm::opt::ArgList &Args, Index: clang/lib/Driver/ToolChains/CommonArgs.cpp =================================================================== --- clang/lib/Driver/ToolChains/CommonArgs.cpp +++ clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1535,6 +1535,36 @@ return Value; } +unsigned tools::DwarfVersionNum(StringRef ArgValue) { + return llvm::StringSwitch<unsigned>(ArgValue) + .Case("-gdwarf-2", 2) + .Case("-gdwarf-3", 3) + .Case("-gdwarf-4", 4) + .Case("-gdwarf-5", 5) + .Default(0); +} + +const Arg *tools::getDwarfNArg(const ArgList &Args) { + return Args.getLastArg(options::OPT_gdwarf_2, options::OPT_gdwarf_3, + options::OPT_gdwarf_4, options::OPT_gdwarf_5, + options::OPT_gdwarf); +} + +unsigned tools::GetDwarfVersion(const ToolChain &TC, + const llvm::opt::ArgList &Args) { + unsigned DwarfVersion = ParseDebugDefaultVersion(TC, Args); + if (const Arg* GDwarfN = getDwarfNArg(Args)) + if (int N = DwarfVersionNum(GDwarfN->getSpelling())) + DwarfVersion = N; + if (DwarfVersion == 0) { + DwarfVersion = TC.GetDefaultDwarfVersion(); + assert(DwarfVersion && + "toolchain default DWARF version must be nonzero"); + } + return DwarfVersion; +} + + void tools::AddAssemblerKPIC(const ToolChain &ToolChain, const ArgList &Args, ArgStringList &CmdArgs) { llvm::Reloc::Model RelocationModel; Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -1057,26 +1057,6 @@ 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) - .Case("-gdwarf-5", 5) - .Default(0); -} - -// Find a DWARF format version option. -// This function is a complementary for DwarfVersionNum(). -static const Arg *getDwarfNArg(const ArgList &Args) { - return Args.getLastArg(options::OPT_gdwarf_2, options::OPT_gdwarf_3, - options::OPT_gdwarf_4, options::OPT_gdwarf_5, - options::OPT_gdwarf); -} - static void RenderDebugEnablingArgs(const ArgList &Args, ArgStringList &CmdArgs, codegenoptions::DebugInfoKind DebugInfoKind, unsigned DwarfVersion, @@ -4235,22 +4215,8 @@ unsigned RequestedDWARFVersion = 0; // DWARF version requested by the user unsigned EffectiveDWARFVersion = 0; // DWARF version TC can generate. It may // be lower than what the user wanted. - unsigned DefaultDWARFVersion = ParseDebugDefaultVersion(TC, Args); if (EmitDwarf) { - // Start with the platform default DWARF version - RequestedDWARFVersion = TC.GetDefaultDwarfVersion(); - assert(RequestedDWARFVersion && - "toolchain default DWARF version must be nonzero"); - - // If the user specified a default DWARF version, that takes precedence - // over the platform default. - if (DefaultDWARFVersion) - RequestedDWARFVersion = DefaultDWARFVersion; - - // Override with a user-specified DWARF version - if (GDwarfN) - if (auto ExplicitVersion = DwarfVersionNum(GDwarfN->getSpelling())) - RequestedDWARFVersion = ExplicitVersion; + RequestedDWARFVersion = GetDwarfVersion(TC, Args); // Clamp effective DWARF version to the max supported by the toolchain. EffectiveDWARFVersion = std::min(RequestedDWARFVersion, TC.getMaxDwarfVersion()); @@ -7978,13 +7944,6 @@ WantDebug = !A->getOption().matches(options::OPT_g0) && !A->getOption().matches(options::OPT_ggdb0); - unsigned DwarfVersion = ParseDebugDefaultVersion(getToolChain(), Args); - if (const Arg *GDwarfN = getDwarfNArg(Args)) - DwarfVersion = DwarfVersionNum(GDwarfN->getSpelling()); - - if (DwarfVersion == 0) - DwarfVersion = getToolChain().GetDefaultDwarfVersion(); - codegenoptions::DebugInfoKind DebugInfoKind = codegenoptions::NoDebugInfo; // Add the -fdebug-compilation-dir flag if needed. @@ -8011,6 +7970,7 @@ // And pass along -I options Args.AddAllArgs(CmdArgs, options::OPT_I); } + unsigned DwarfVersion = GetDwarfVersion(getToolChain(), Args); RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DwarfVersion, llvm::DebuggerKind::Default); renderDwarfFormat(D, Triple, Args, CmdArgs, DwarfVersion);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits