Author: Yangyu Chen
Date: 2026-02-28T01:45:52+08:00
New Revision: 7f0a343a8ec48b41e3866cdbabfc8740985a44f3

URL: 
https://github.com/llvm/llvm-project/commit/7f0a343a8ec48b41e3866cdbabfc8740985a44f3
DIFF: 
https://github.com/llvm/llvm-project/commit/7f0a343a8ec48b41e3866cdbabfc8740985a44f3.diff

LOG: [flang] Implement -grecord-command-line for Flang (#181686)

Enable Flang to match Clang behavior for command-line recording in DWARF
producer strings when using -grecord-command-line.

Signed-off-by: Yangyu Chen <[email protected]>

Added: 
    flang/test/Driver/grecord-command-line.f90
    flang/test/Transforms/debug-dwarf-debug-flags.fir

Modified: 
    clang/include/clang/Options/Options.td
    flang/include/flang/Frontend/CodeGenOptions.h
    flang/include/flang/Optimizer/Passes/Pipelines.h
    flang/include/flang/Optimizer/Transforms/Passes.td
    flang/include/flang/Tools/CrossToolHelpers.h
    flang/lib/Frontend/CompilerInvocation.cpp
    flang/lib/Optimizer/Passes/Pipelines.cpp
    flang/lib/Optimizer/Transforms/AddDebugInfo.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index f024dc4055e22..4dbfe0eb6f1af 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -5005,9 +5005,11 @@ def gxcoff : Joined<["-"], "gxcoff">, Group<g_Group>, 
Flags<[Unsupported]>;
 def gvms : Joined<["-"], "gvms">, Group<g_Group>, Flags<[Unsupported]>;
 def gtoggle : Flag<["-"], "gtoggle">, Group<g_flags_Group>, 
Flags<[Unsupported]>;
 def grecord_command_line : Flag<["-"], "grecord-command-line">,
-  Group<g_flags_Group>;
+  Group<g_flags_Group>,
+  Visibility<[ClangOption, FlangOption]>;
 def gno_record_command_line : Flag<["-"], "gno-record-command-line">,
-  Group<g_flags_Group>;
+  Group<g_flags_Group>,
+  Visibility<[ClangOption, FlangOption]>;
 def : Flag<["-"], "grecord-gcc-switches">, Alias<grecord_command_line>;
 def : Flag<["-"], "gno-record-gcc-switches">, Alias<gno_record_command_line>;
 defm strict_dwarf : BoolOption<"g", "strict-dwarf",
@@ -7951,6 +7953,9 @@ def debug_info_kind_EQ : Joined<["-"], 
"debug-info-kind=">;
 def record_command_line : Separate<["-"], "record-command-line">,
   HelpText<"The string to embed in the .LLVM.command.line section.">,
   MarshallingInfoString<CodeGenOpts<"RecordCommandLine">>;
+def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">,
+  HelpText<"The string to embed in the Dwarf debug flags record.">,
+  MarshallingInfoString<CodeGenOpts<"DwarfDebugFlags">>;
 def dwarf_version_EQ : Joined<["-"], "dwarf-version=">,
   MarshallingInfoInt<CodeGenOpts<"DwarfVersion">>;
 
@@ -7972,9 +7977,6 @@ def debugger_tuning_EQ : Joined<["-"], 
"debugger-tuning=">,
   Values<"gdb,lldb,sce,dbx">,
   NormalizedValuesScope<"llvm::DebuggerKind">, NormalizedValues<["GDB", 
"LLDB", "SCE", "DBX"]>,
   MarshallingInfoEnum<CodeGenOpts<"DebuggerTuning">, "Default">;
-def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">,
-  HelpText<"The string to embed in the Dwarf debug flags record.">,
-  MarshallingInfoString<CodeGenOpts<"DwarfDebugFlags">>;
 def compress_debug_sections_EQ : Joined<["-", "--"], 
"compress-debug-sections=">,
     HelpText<"DWARF debug sections compression type">, 
Values<"none,zlib,zstd">,
     NormalizedValuesScope<"llvm::DebugCompressionType">, 
NormalizedValues<["None", "Zlib", "Zstd"]>,

diff  --git a/flang/include/flang/Frontend/CodeGenOptions.h 
b/flang/include/flang/Frontend/CodeGenOptions.h
index 3dca169d43b39..5a141e3c0a87d 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.h
+++ b/flang/include/flang/Frontend/CodeGenOptions.h
@@ -73,6 +73,11 @@ class CodeGenOptions : public CodeGenOptionsBase {
   /// The string containing the commandline for the llvm.commandline metadata.
   std::optional<std::string> RecordCommandLine;
 
+  /// The value from -dwarf-debug-flags to append to DW_AT_producer.
+  /// This is typically a reconstructed user command line (e.g. from
+  /// -grecord-command-line) and may contain multiple space-separated flags.
+  std::string DwarfDebugFlags;
+
   /// The name of the file to which the backend should save YAML optimization
   /// records.
   std::string OptRecordFile;

diff  --git a/flang/include/flang/Optimizer/Passes/Pipelines.h 
b/flang/include/flang/Optimizer/Passes/Pipelines.h
index 1a7ff4ff3dfa2..8f2ff5f82299d 100644
--- a/flang/include/flang/Optimizer/Passes/Pipelines.h
+++ b/flang/include/flang/Optimizer/Passes/Pipelines.h
@@ -103,7 +103,9 @@ void 
addCompilerGeneratedNamesConversionPass(mlir::PassManager &pm);
 void addDebugInfoPass(mlir::PassManager &pm,
                       llvm::codegenoptions::DebugInfoKind debugLevel,
                       llvm::OptimizationLevel optLevel,
-                      llvm::StringRef inputFilename, int32_t dwarfVersion);
+                      llvm::StringRef inputFilename, int32_t dwarfVersion,
+                      llvm::StringRef splitDwarfFile,
+                      llvm::StringRef dwarfDebugFlags);
 
 /// Create FIRToLLVMPassOptions from pipeline configuration.
 FIRToLLVMPassOptions
@@ -164,7 +166,8 @@ void createDebugPasses(mlir::PassManager &pm,
                        llvm::codegenoptions::DebugInfoKind debugLevel,
                        llvm::OptimizationLevel OptLevel,
                        llvm::StringRef inputFilename, int32_t dwarfVersion,
-                       llvm::StringRef splitDwarfFile);
+                       llvm::StringRef splitDwarfFile,
+                       llvm::StringRef dwarfDebugFlags);
 
 void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
                                          MLIRToLLVMPassPipelineConfig config,

diff  --git a/flang/include/flang/Optimizer/Transforms/Passes.td 
b/flang/include/flang/Optimizer/Transforms/Passes.td
index d812e271b158d..bdee252d14c72 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.td
+++ b/flang/include/flang/Optimizer/Transforms/Passes.td
@@ -260,7 +260,10 @@ def AddDebugInfo : Pass<"add-debug-info", 
"mlir::ModuleOp"> {
            "dwarf version">,
     Option<"splitDwarfFile", "split-dwarf-file",
            "std::string", /*default=*/"std::string{}",
-           "Name of the split dwarf file">
+           "Name of the split dwarf file">,
+    Option<"dwarfDebugFlags", "dwarf-debug-flags",
+           "std::string", /*default=*/"std::string{}",
+           "Command-line flags to append to DWARF producer">
 
   ];
 }

diff  --git a/flang/include/flang/Tools/CrossToolHelpers.h 
b/flang/include/flang/Tools/CrossToolHelpers.h
index 44fb252d2b366..f29fc8ef0ea56 100644
--- a/flang/include/flang/Tools/CrossToolHelpers.h
+++ b/flang/include/flang/Tools/CrossToolHelpers.h
@@ -110,6 +110,7 @@ struct MLIRToLLVMPassPipelineConfig : public 
FlangEPCallBacks {
     }
     DwarfVersion = opts.DwarfVersion;
     SplitDwarfFile = opts.SplitDwarfFile;
+    DwarfDebugFlags = opts.DwarfDebugFlags;
   }
 
   llvm::OptimizationLevel OptLevel; ///< optimisation level
@@ -148,6 +149,7 @@ struct MLIRToLLVMPassPipelineConfig : public 
FlangEPCallBacks {
           CX_Full; ///< Method for calculating complex number division
   int32_t DwarfVersion = 0; ///< Version of DWARF debug info to generate
   std::string SplitDwarfFile = ""; ///< File name for the split debug info
+  std::string DwarfDebugFlags = ""; ///< Debug flags to append to DWARF 
producer
 };
 
 struct OffloadModuleOpts {

diff  --git a/flang/lib/Frontend/CompilerInvocation.cpp 
b/flang/lib/Frontend/CompilerInvocation.cpp
index fc4975f9592eb..72b766e52ab3b 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -165,6 +165,11 @@ static bool 
parseDebugArgs(Fortran::frontend::CodeGenOptions &opts,
             args.getLastArg(clang::options::OPT_split_dwarf_output))
       opts.SplitDwarfOutput = a->getValue();
   }
+
+  if (const llvm::opt::Arg *arg =
+          args.getLastArg(clang::options::OPT_dwarf_debug_flags))
+    opts.DwarfDebugFlags = arg->getValue();
+
   return true;
 }
 

diff  --git a/flang/lib/Optimizer/Passes/Pipelines.cpp 
b/flang/lib/Optimizer/Passes/Pipelines.cpp
index 5927fff960270..bb1ad84523c82 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -97,13 +97,15 @@ void addDebugInfoPass(mlir::PassManager &pm,
                       llvm::codegenoptions::DebugInfoKind debugLevel,
                       llvm::OptimizationLevel optLevel,
                       llvm::StringRef inputFilename, int32_t dwarfVersion,
-                      llvm::StringRef splitDwarfFile) {
+                      llvm::StringRef splitDwarfFile,
+                      llvm::StringRef dwarfDebugFlags) {
   fir::AddDebugInfoOptions options;
   options.debugLevel = getEmissionKind(debugLevel);
   options.isOptimized = optLevel != llvm::OptimizationLevel::O0;
   options.inputFilename = inputFilename;
   options.dwarfVersion = dwarfVersion;
   options.splitDwarfFile = splitDwarfFile;
+  options.dwarfDebugFlags = dwarfDebugFlags;
   addPassConditionally(pm, disableDebugInfo,
                        [&]() { return fir::createAddDebugInfoPass(options); });
 }
@@ -361,10 +363,11 @@ void createDebugPasses(mlir::PassManager &pm,
                        llvm::codegenoptions::DebugInfoKind debugLevel,
                        llvm::OptimizationLevel OptLevel,
                        llvm::StringRef inputFilename, int32_t dwarfVersion,
-                       llvm::StringRef splitDwarfFile) {
+                       llvm::StringRef splitDwarfFile,
+                       llvm::StringRef dwarfDebugFlags) {
   if (debugLevel != llvm::codegenoptions::NoDebugInfo)
     addDebugInfoPass(pm, debugLevel, OptLevel, inputFilename, dwarfVersion,
-                     splitDwarfFile);
+                     splitDwarfFile, dwarfDebugFlags);
 }
 
 void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm,
@@ -383,7 +386,8 @@ void createDefaultFIRCodeGenPassPipeline(mlir::PassManager 
&pm,
       pm, (config.DebugInfo != llvm::codegenoptions::NoDebugInfo));
   fir::addExternalNameConversionPass(pm, config.Underscoring);
   fir::createDebugPasses(pm, config.DebugInfo, config.OptLevel, inputFilename,
-                         config.DwarfVersion, config.SplitDwarfFile);
+                         config.DwarfVersion, config.SplitDwarfFile,
+                         config.DwarfDebugFlags);
   fir::addTargetRewritePass(pm);
   fir::addCompilerGeneratedNamesConversionPass(pm);
 

diff  --git a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp 
b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
index 63698fdb88909..c42f5a29ecd62 100644
--- a/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
+++ b/flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
@@ -927,8 +927,12 @@ void AddDebugInfoPass::runOnOperation() {
 
   mlir::LLVM::DIFileAttr fileAttr =
       mlir::LLVM::DIFileAttr::get(context, fileName, filePath);
-  mlir::StringAttr producer =
-      mlir::StringAttr::get(context, Fortran::common::getFlangFullVersion());
+  // Match Clang style by starting with the full compiler version and
+  // appending -dwarf-debug-flags content when provided.
+  std::string producerString = Fortran::common::getFlangFullVersion();
+  if (!dwarfDebugFlags.empty())
+    producerString += " " + dwarfDebugFlags;
+  mlir::StringAttr producer = mlir::StringAttr::get(context, producerString);
   mlir::LLVM::DICompileUnitAttr cuAttr = mlir::LLVM::DICompileUnitAttr::get(
       mlir::DistinctAttr::create(mlir::UnitAttr::get(context)),
       llvm::dwarf::getLanguage("DW_LANG_Fortran95"), fileAttr, producer,

diff  --git a/flang/test/Driver/grecord-command-line.f90 
b/flang/test/Driver/grecord-command-line.f90
new file mode 100644
index 0000000000000..269381e464e7d
--- /dev/null
+++ b/flang/test/Driver/grecord-command-line.f90
@@ -0,0 +1,14 @@
+! This checks that -grecord-command-line is forwarded by the flang driver to
+! an FC1 -dwarf-debug-flags argument and that -gno-record-command-line
+! disables it, matching clang behavior.
+!
+! RUN: %flang -### -grecord-command-line %s 2>&1 | FileCheck 
--check-prefix=GRECORD %s
+! RUN: %flang -### -gno-record-command-line %s 2>&1 | FileCheck 
--check-prefix=GNO_RECORD %s
+! RUN: %flang -### -grecord-command-line -gno-record-command-line %s 2>&1 | 
FileCheck --check-prefix=GNO_RECORD %s
+!
+! GRECORD: "-dwarf-debug-flags"
+!
+! GNO_RECORD-NOT: "-dwarf-debug-flags"
+
+program p
+end program p

diff  --git a/flang/test/Transforms/debug-dwarf-debug-flags.fir 
b/flang/test/Transforms/debug-dwarf-debug-flags.fir
new file mode 100644
index 0000000000000..78f3989589e51
--- /dev/null
+++ b/flang/test/Transforms/debug-dwarf-debug-flags.fir
@@ -0,0 +1,14 @@
+// Test the dwarf-debug-flags option will show up in the generated debug info.
+// RUN: fir-opt --add-debug-info="debug-level=Full 
dwarf-debug-flags=\"-grecord-command-line -O2\"" \
+// RUN:   --mlir-print-debuginfo %s | FileCheck --check-prefix=CHECK-FLAGS %s
+
+module {
+  func.func @_QPs() {
+    return loc(#loc_s)
+  } loc(#loc_s)
+} loc(#loc_module)
+#loc_module = loc("simple.f90":1:1)
+#loc_s = loc("simple.f90":2:1)
+
+// CHECK-FLAGS: #llvm.di_compile_unit<
+// CHECK-FLAGS: producer = "{{.*}} -grecord-command-line -O2"


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to