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

Reply via email to