]> granicus.if.org Git - clang/commitdiff
Driver: extract debugging related options (NFC)
authorSaleem Abdulrasool <compnerd@compnerd.org>
Sun, 3 Sep 2017 04:46:59 +0000 (04:46 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Sun, 3 Sep 2017 04:46:59 +0000 (04:46 +0000)
Out-of-line the logic for selecting the debug information handling.
This is still split across the new function and partially inline in the
job construction.  This is needed since the split portion attempts to
record the "-cc1" arguments.  This needs to be the very last item to
ensure that all the flags are recorded.  NFC.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@312435 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Driver/ToolChains/Clang.cpp

index 512e81d78373e2cce13700e5292ad90ad8e51860..c428f41b7c0bdbd72f0848d8a5e284747a25988c 100644 (file)
@@ -2758,6 +2758,170 @@ static void RenderDiagnosticsOptions(const Driver &D, const ArgList &Args,
     CmdArgs.push_back("-fno-spell-checking");
 }
 
+static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
+                               const llvm::Triple &T, const ArgList &Args,
+                               bool EmitCodeView, bool IsWindowsMSVC,
+                               ArgStringList &CmdArgs,
+                               codegenoptions::DebugInfoKind &DebugInfoKind,
+                               const Arg *&SplitDWARFArg) {
+  bool IsPS4CPU = T.isPS4CPU();
+
+  if (Args.hasFlag(options::OPT_fdebug_info_for_profiling,
+                   options::OPT_fno_debug_info_for_profiling, false))
+    CmdArgs.push_back("-fdebug-info-for-profiling");
+
+  // 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 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 = TC.getDefaultDebuggerTuning();
+
+  bool SplitDWARFInlining =
+      Args.hasFlag(options::OPT_fsplit_dwarf_inlining,
+                   options::OPT_fno_split_dwarf_inlining, true);
+
+  Args.ClaimAllArgs(options::OPT_g_Group);
+
+  SplitDWARFArg = Args.getLastArg(options::OPT_gsplit_dwarf);
+
+  if (const Arg *A = Args.getLastArg(options::OPT_g_Group)) {
+    // 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.
+      // This gets a bit more complicated if you've disabled inline info in the
+      // skeleton CUs (SplitDWARFInlining) - then there's value in composing
+      // split-dwarf and line-tables-only, so let those compose naturally in
+      // that case.
+      // And if you just turned off debug info, (-gsplit-dwarf -g0) - do that.
+      if (SplitDWARFArg) {
+        if (A->getIndex() > SplitDWARFArg->getIndex()) {
+          if (DebugInfoKind == codegenoptions::NoDebugInfo ||
+              (DebugInfoKind == codegenoptions::DebugLineTablesOnly &&
+               SplitDWARFInlining))
+            SplitDWARFArg = nullptr;
+        } else if (SplitDWARFInlining)
+          DebugInfoKind = codegenoptions::NoDebugInfo;
+      }
+    } else {
+      // For any other 'g' option, use Limited.
+      DebugInfoKind = codegenoptions::LimitedDebugInfo;
+    }
+  }
+
+  // If a debugger tuning argument appeared, remember it.
+  if (const 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 (const Arg *A =
+          Args.getLastArg(options::OPT_gdwarf_2, options::OPT_gdwarf_3,
+                          options::OPT_gdwarf_4, options::OPT_gdwarf_5))
+    DWARFVersion = DwarfVersionNum(A->getSpelling());
+
+  // Forward -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 = TC.GetDefaultDwarfVersion();
+  }
+
+  // We ignore flag -gstrict-dwarf for now.
+  // And we handle flag -grecord-gcc-switches later with DWARFDebugFlags.
+  Args.ClaimAllArgs(options::OPT_g_flags_Group);
+
+  // Column info is included by default for everything except PS4 and CodeView.
+  // Clang doesn't track end columns, just starting columns, which, in theory,
+  // is fine for CodeView (and PDB).  In practice, however, the Microsoft
+  // debuggers don't handle missing end columns well, so it's better not to
+  // include any column info.
+  if (Args.hasFlag(options::OPT_gcolumn_info, options::OPT_gno_column_info,
+                   /*Default=*/ !IsPS4CPU && !(IsWindowsMSVC && EmitCodeView)))
+    CmdArgs.push_back("-dwarf-column-info");
+
+  // FIXME: Move backend command line options to the module.
+  // If -gline-tables-only is the last option it wins.
+  if (DebugInfoKind != codegenoptions::DebugLineTablesOnly &&
+      Args.hasArg(options::OPT_gmodules)) {
+    DebugInfoKind = codegenoptions::LimitedDebugInfo;
+    CmdArgs.push_back("-dwarf-ext-refs");
+    CmdArgs.push_back("-fmodule-format=obj");
+  }
+
+  // -gsplit-dwarf should turn on -g and enable the backend dwarf
+  // splitting and extraction.
+  // FIXME: Currently only works on Linux.
+  if (T.isOSLinux()) {
+    if (!SplitDWARFInlining)
+      CmdArgs.push_back("-fno-split-dwarf-inlining");
+
+    if (SplitDWARFArg) {
+      if (DebugInfoKind == codegenoptions::NoDebugInfo)
+        DebugInfoKind = codegenoptions::LimitedDebugInfo;
+      CmdArgs.push_back("-enable-split-dwarf");
+    }
+  }
+
+  // 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,
+                                    TC.GetDefaultStandaloneDebug());
+  if (DebugInfoKind == codegenoptions::LimitedDebugInfo && NeedFullDebug)
+    DebugInfoKind = codegenoptions::FullDebugInfo;
+
+  RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DWARFVersion,
+                          DebuggerTuning);
+
+  // -fdebug-macro turns on macro debug info generation.
+  if (Args.hasFlag(options::OPT_fdebug_macro, options::OPT_fno_debug_macro,
+                   false))
+    CmdArgs.push_back("-debug-info-macro");
+
+  // -ggnu-pubnames turns on gnu style pubnames in the backend.
+  if (Args.hasArg(options::OPT_ggnu_pubnames)) {
+    CmdArgs.push_back("-backend-option");
+    CmdArgs.push_back("-generate-gnu-dwarf-pub-sections");
+  }
+
+  // -gdwarf-aranges turns on the emission of the aranges section in the
+  // backend.
+  // Always enabled on the PS4.
+  if (Args.hasArg(options::OPT_gdwarf_aranges) || IsPS4CPU) {
+    CmdArgs.push_back("-backend-option");
+    CmdArgs.push_back("-generate-arange-section");
+  }
+
+  if (Args.hasFlag(options::OPT_fdebug_types_section,
+                   options::OPT_fno_debug_types_section, false)) {
+    CmdArgs.push_back("-backend-option");
+    CmdArgs.push_back("-generate-type-units");
+  }
+
+  RenderDebugInfoCompressionArgs(Args, CmdArgs, D);
+}
+
 void Clang::ConstructJob(Compilation &C, const JobAction &JA,
                          const InputInfo &Output, const InputInfoList &Inputs,
                          const ArgList &Args, const char *LinkingOutput) const {
@@ -2786,7 +2950,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   bool IsWindowsGNU = RawTriple.isWindowsGNUEnvironment();
   bool IsWindowsCygnus = RawTriple.isWindowsCygwinEnvironment();
   bool IsWindowsMSVC = RawTriple.isWindowsMSVCEnvironment();
-  bool IsPS4CPU = RawTriple.isPS4CPU();
   bool IsIAMCU = RawTriple.isOSIAMCU();
 
   // Adjust IsWindowsXYZ for CUDA compilations.  Even when compiling in device
@@ -3274,17 +3437,6 @@ 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 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.
   codegenoptions::DebugInfoKind DebugInfoKind = codegenoptions::NoDebugInfo;
   bool EmitCodeView = false;
@@ -3294,6 +3446,22 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   if (D.IsCLMode())
     AddClangCLArgs(Args, InputType, CmdArgs, &DebugInfoKind, &EmitCodeView);
 
+  const Arg *SplitDWARFArg = nullptr;
+  RenderDebugOptions(getToolChain(), D, RawTriple, Args, EmitCodeView,
+                     IsWindowsMSVC, CmdArgs, DebugInfoKind, SplitDWARFArg);
+
+  // Add the split debug info name to the command lines here so we
+  // can propagate it to the backend.
+  bool SplitDWARF = SplitDWARFArg && RawTriple.isOSLinux() &&
+                    (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA) ||
+                     isa<BackendJobAction>(JA));
+  const char *SplitDWARFOut;
+  if (SplitDWARF) {
+    CmdArgs.push_back("-split-dwarf-file");
+    SplitDWARFOut = SplitDebugName(Args, Input);
+    CmdArgs.push_back(SplitDWARFOut);
+  }
+
   // Pass the linker version in use.
   if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
     CmdArgs.push_back("-target-linker-version");
@@ -3340,139 +3508,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
                                                  : "-");
   }
 
-  bool splitDwarfInlining =
-      Args.hasFlag(options::OPT_fsplit_dwarf_inlining,
-                   options::OPT_fno_split_dwarf_inlining, true);
-
-  Args.ClaimAllArgs(options::OPT_g_Group);
-  Arg *SplitDwarfArg = Args.getLastArg(options::OPT_gsplit_dwarf);
-  if (Arg *A = Args.getLastArg(options::OPT_g_Group)) {
-    // 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.)
-      // This gets a bit more complicated if you've disabled inline info in the
-      // skeleton CUs (splitDwarfInlining) - then there's value in composing
-      // split-dwarf and line-tables-only, so let those compose naturally in
-      // that case.
-      // And if you just turned off debug info, (-gsplit-dwarf -g0) - do that.
-      if (SplitDwarfArg) {
-        if (A->getIndex() > SplitDwarfArg->getIndex()) {
-          if (DebugInfoKind == codegenoptions::NoDebugInfo ||
-              (DebugInfoKind == codegenoptions::DebugLineTablesOnly &&
-               splitDwarfInlining))
-            SplitDwarfArg = nullptr;
-        } else if (splitDwarfInlining)
-          DebugInfoKind = codegenoptions::NoDebugInfo;
-      }
-    } else
-      // For any other 'g' option, use Limited.
-      DebugInfoKind = codegenoptions::LimitedDebugInfo;
-  }
-
-  // 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, options::OPT_gdwarf_5))
-    DwarfVersion = DwarfVersionNum(A->getSpelling());
-
-  // Forward -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 flag -gstrict-dwarf for now.
-  // And we handle flag -grecord-gcc-switches later with DwarfDebugFlags.
-  Args.ClaimAllArgs(options::OPT_g_flags_Group);
-
-  // Column info is included by default for everything except PS4 and CodeView.
-  // Clang doesn't track end columns, just starting columns, which, in theory,
-  // is fine for CodeView (and PDB).  In practice, however, the Microsoft
-  // debuggers don't handle missing end columns well, so it's better not to
-  // include any column info.
-  if (Args.hasFlag(options::OPT_gcolumn_info, options::OPT_gno_column_info,
-                   /*Default=*/ !IsPS4CPU && !(IsWindowsMSVC && EmitCodeView)))
-    CmdArgs.push_back("-dwarf-column-info");
-
-  // FIXME: Move backend command line options to the module.
-  // If -gline-tables-only is the last option it wins.
-  if (DebugInfoKind != codegenoptions::DebugLineTablesOnly &&
-      Args.hasArg(options::OPT_gmodules)) {
-    DebugInfoKind = codegenoptions::LimitedDebugInfo;
-    CmdArgs.push_back("-dwarf-ext-refs");
-    CmdArgs.push_back("-fmodule-format=obj");
-  }
-
-  // -gsplit-dwarf should turn on -g and enable the backend dwarf
-  // splitting and extraction.
-  // FIXME: Currently only works on Linux.
-  if (RawTriple.isOSLinux()) {
-    if (!splitDwarfInlining)
-      CmdArgs.push_back("-fno-split-dwarf-inlining");
-    if (SplitDwarfArg) {
-      if (DebugInfoKind == codegenoptions::NoDebugInfo)
-        DebugInfoKind = codegenoptions::LimitedDebugInfo;
-      CmdArgs.push_back("-enable-split-dwarf");
-    }
-  }
-
-  // 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,
-                          DebuggerTuning);
-
-  // -fdebug-macro turns on macro debug info generation.
-  if (Args.hasFlag(options::OPT_fdebug_macro, options::OPT_fno_debug_macro,
-                   false))
-    CmdArgs.push_back("-debug-info-macro");
-
-  // -ggnu-pubnames turns on gnu style pubnames in the backend.
-  if (Args.hasArg(options::OPT_ggnu_pubnames)) {
-    CmdArgs.push_back("-backend-option");
-    CmdArgs.push_back("-generate-gnu-dwarf-pub-sections");
-  }
-
-  // -gdwarf-aranges turns on the emission of the aranges section in the
-  // backend.
-  // Always enabled on the PS4.
-  if (Args.hasArg(options::OPT_gdwarf_aranges) || IsPS4CPU) {
-    CmdArgs.push_back("-backend-option");
-    CmdArgs.push_back("-generate-arange-section");
-  }
-
-  if (Args.hasFlag(options::OPT_fdebug_types_section,
-                   options::OPT_fno_debug_types_section, false)) {
-    CmdArgs.push_back("-backend-option");
-    CmdArgs.push_back("-generate-type-units");
-  }
-
-  RenderDebugInfoCompressionArgs(Args, CmdArgs, D);
-
   bool UseSeparateSections = isUseSeparateSections(Triple);
 
   if (Args.hasFlag(options::OPT_ffunction_sections,
@@ -3939,10 +3974,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
       A->render(Args, CmdArgs);
   }
 
-  if (Args.hasFlag(options::OPT_fdebug_info_for_profiling,
-                   options::OPT_fno_debug_info_for_profiling, false))
-    CmdArgs.push_back("-fdebug-info-for-profiling");
-
   RenderBuiltinOptions(getToolChain(), RawTriple, Args, CmdArgs);
 
   if (!Args.hasFlag(options::OPT_fassume_sane_operator_new,
@@ -4502,18 +4533,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
     CmdArgs.push_back(Args.MakeArgString(Flags));
   }
 
-  // Add the split debug info name to the command lines here so we
-  // can propagate it to the backend.
-  bool SplitDwarf = SplitDwarfArg && RawTriple.isOSLinux() &&
-                    (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA) ||
-                     isa<BackendJobAction>(JA));
-  const char *SplitDwarfOut;
-  if (SplitDwarf) {
-    CmdArgs.push_back("-split-dwarf-file");
-    SplitDwarfOut = SplitDebugName(Args, Input);
-    CmdArgs.push_back(SplitDwarfOut);
-  }
-
   // Host-side cuda compilation receives device-side outputs as Inputs[1...].
   // Include them with -fcuda-include-gpubinary.
   if (IsCuda && Inputs.size() > 1)
@@ -4586,8 +4605,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   // Handle the debug info splitting at object creation time if we're
   // creating an object.
   // TODO: Currently only works on linux with newer objcopy.
-  if (SplitDwarf && Output.getType() == types::TY_Object)
-    SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, SplitDwarfOut);
+  if (SplitDWARF && Output.getType() == types::TY_Object)
+    SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, SplitDWARFOut);
 
   if (Arg *A = Args.getLastArg(options::OPT_pg))
     if (Args.hasArg(options::OPT_fomit_frame_pointer))