[flang-commits] [flang] [flang] Fix compiler invocation issue (#232487) (PR #235472)

via flang-commits flang-commits at lists.llvm.org
Sun Oct 25 08:40:52 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-driver

Author: Harshit (Harshit2906)

<details>
<summary>Changes</summary>

Fixes #<!-- -->232487

---

Patch is 100.48 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/235472.diff


1 Files Affected:

- (modified) flang/lib/Frontend/CompilerInvocation.cpp (+365-1386) 


``````````diff
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 38e66aad693cbc..46c6c87f534811 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -11,44 +11,34 @@
 //===----------------------------------------------------------------------===//
 
 #include "flang/Frontend/CompilerInvocation.h"
+#include "flang/Common/Fortran-features.h"
+#include "flang/Common/OpenMP-features.h"
+#include "flang/Common/Version.h"
 #include "flang/Frontend/CodeGenOptions.h"
 #include "flang/Frontend/PreprocessorOptions.h"
 #include "flang/Frontend/TargetOptions.h"
-#include "flang/Optimizer/Passes/CommandLineOpts.h"
 #include "flang/Semantics/semantics.h"
-#include "flang/Support/Fortran-features.h"
-#include "flang/Support/OpenMP-features.h"
-#include "flang/Support/Version.h"
-#include "flang/Tools/TargetSetup.h"
 #include "flang/Version.inc"
+#include "clang/Basic/AllDiagnostics.h"
 #include "clang/Basic/DiagnosticDriver.h"
-#include "clang/Basic/DiagnosticFrontend.h"
 #include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Driver/CommonArgs.h"
-#include "clang/Driver/Driver.h"
-#include "clang/Options/OptionUtils.h"
-#include "clang/Options/Options.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringExtras.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/OptionUtils.h"
+#include "clang/Driver/Options.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Frontend/Debug/Options.h"
-#include "llvm/Frontend/Driver/CodeGenOptions.h"
 #include "llvm/Option/Arg.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Option/OptTable.h"
-#include "llvm/Support/CodeGen.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FileUtilities.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Process.h"
-#include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/Host.h"
 #include "llvm/TargetParser/Triple.h"
-#include <algorithm>
 #include <cstdlib>
-#include <limits>
 #include <memory>
 #include <optional>
 
@@ -73,8 +63,8 @@ CompilerInvocationBase::~CompilerInvocationBase() = default;
 static bool parseShowColorsArgs(const llvm::opt::ArgList &args,
                                 bool defaultColor = true) {
   // Color diagnostics default to auto ("on" if terminal supports) in the
-  // compiler driver `flang` but default to off in the frontend driver
-  // `flang -fc1`, needing an explicit OPT_fdiagnostics_color.
+  // compiler driver `flang-new` but default to off in the frontend driver
+  // `flang-new -fc1`, needing an explicit OPT_fdiagnostics_color.
   // Support both clang's -f[no-]color-diagnostics and gcc's
   // -f[no-]diagnostics-colors[=never|always|auto].
   enum {
@@ -85,11 +75,11 @@ static bool parseShowColorsArgs(const llvm::opt::ArgList &args,
 
   for (auto *a : args) {
     const llvm::opt::Option &opt = a->getOption();
-    if (opt.matches(clang::options::OPT_fcolor_diagnostics)) {
+    if (opt.matches(clang::driver::options::OPT_fcolor_diagnostics)) {
       showColors = Colors_On;
-    } else if (opt.matches(clang::options::OPT_fno_color_diagnostics)) {
+    } else if (opt.matches(clang::driver::options::OPT_fno_color_diagnostics)) {
       showColors = Colors_Off;
-    } else if (opt.matches(clang::options::OPT_fdiagnostics_color_EQ)) {
+    } else if (opt.matches(clang::driver::options::OPT_fdiagnostics_color_EQ)) {
       llvm::StringRef value(a->getValue());
       if (value == "always")
         showColors = Colors_On;
@@ -108,15 +98,17 @@ static bool parseShowColorsArgs(const llvm::opt::ArgList &args,
 /// Extracts the optimisation level from \a args.
 static unsigned getOptimizationLevel(llvm::opt::ArgList &args,
                                      clang::DiagnosticsEngine &diags) {
-  unsigned defaultOpt = 0;
+  unsigned defaultOpt = llvm::CodeGenOpt::None;
 
-  if (llvm::opt::Arg *a = args.getLastArg(clang::options::OPT_O_Group)) {
-    if (a->getOption().matches(clang::options::OPT_O0))
-      return 0;
+  if (llvm::opt::Arg *a =
+          args.getLastArg(clang::driver::options::OPT_O_Group)) {
+    if (a->getOption().matches(clang::driver::options::OPT_O0))
+      return llvm::CodeGenOpt::None;
 
-    assert(a->getOption().matches(clang::options::OPT_O));
+    assert(a->getOption().matches(clang::driver::options::OPT_O));
 
-    return getLastArgIntValue(args, clang::options::OPT_O, defaultOpt, diags);
+    return getLastArgIntValue(args, clang::driver::options::OPT_O, defaultOpt,
+                              diags);
   }
 
   return defaultOpt;
@@ -124,8 +116,7 @@ static unsigned getOptimizationLevel(llvm::opt::ArgList &args,
 
 bool Fortran::frontend::parseDiagnosticArgs(clang::DiagnosticOptions &opts,
                                             llvm::opt::ArgList &args) {
-  opts.setShowColors(parseShowColorsArgs(args) ? clang::ShowColorsKind::On
-                                               : clang::ShowColorsKind::Off);
+  opts.ShowColors = parseShowColorsArgs(args);
 
   return true;
 }
@@ -135,7 +126,7 @@ static bool parseDebugArgs(Fortran::frontend::CodeGenOptions &opts,
                            clang::DiagnosticsEngine &diags) {
   using DebugInfoKind = llvm::codegenoptions::DebugInfoKind;
   if (llvm::opt::Arg *arg =
-          args.getLastArg(clang::options::OPT_debug_info_kind_EQ)) {
+          args.getLastArg(clang::driver::options::OPT_debug_info_kind_EQ)) {
     std::optional<DebugInfoKind> val =
         llvm::StringSwitch<std::optional<DebugInfoKind>>(arg->getValue())
             .Case("line-tables-only", llvm::codegenoptions::DebugLineTablesOnly)
@@ -153,337 +144,58 @@ static bool parseDebugArgs(Fortran::frontend::CodeGenOptions &opts,
     }
     opts.setDebugInfo(val.value());
     if (val != llvm::codegenoptions::DebugLineTablesOnly &&
-        val != llvm::codegenoptions::DebugDirectivesOnly &&
-        val != llvm::codegenoptions::FullDebugInfo &&
         val != llvm::codegenoptions::NoDebugInfo) {
       const auto debugWarning = diags.getCustomDiagID(
           clang::DiagnosticsEngine::Warning, "Unsupported debug option: %0");
       diags.Report(debugWarning) << arg->getValue();
     }
-    opts.DwarfVersion =
-        getLastArgIntValue(args, clang::options::OPT_dwarf_version_EQ,
-                           /*Default=*/0, diags);
-    if (const llvm::opt::Arg *a =
-            args.getLastArg(clang::options::OPT_split_dwarf_file))
-      opts.SplitDwarfFile = a->getValue();
-    if (const llvm::opt::Arg *a =
-            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();
-
-  opts.DebugInfoForProfiling =
-      args.hasArg(clang::options::OPT_fdebug_info_for_profiling);
-
-  if (const llvm::opt::Arg *a =
-          args.getLastArg(clang::options::OPT_compress_debug_sections_EQ)) {
-    auto type = llvm::StringSwitch<std::optional<llvm::DebugCompressionType>>(
-                    a->getValue())
-                    .Case("none", llvm::DebugCompressionType::None)
-                    .Case("zlib", llvm::DebugCompressionType::Zlib)
-                    .Case("zstd", llvm::DebugCompressionType::Zstd)
-                    .Default(std::nullopt);
-    if (type) {
-      opts.setCompressDebugSections(*type);
-    } else {
-      diags.Report(clang::diag::err_drv_invalid_value)
-          << a->getAsString(args) << a->getValue();
-      return false;
-    }
-  }
-
-  return true;
-}
-
-static bool parseDoConcurrentMapping(Fortran::frontend::CodeGenOptions &opts,
-                                     llvm::opt::ArgList &args,
-                                     clang::DiagnosticsEngine &diags) {
-  llvm::opt::Arg *arg =
-      args.getLastArg(clang::options::OPT_fdo_concurrent_to_openmp_EQ);
-  if (!arg)
-    return true;
-
-  using DoConcurrentMappingKind =
-      Fortran::frontend::CodeGenOptions::DoConcurrentMappingKind;
-  std::optional<DoConcurrentMappingKind> val =
-      llvm::StringSwitch<std::optional<DoConcurrentMappingKind>>(
-          arg->getValue())
-          .Case("none", DoConcurrentMappingKind::DCMK_None)
-          .Case("host", DoConcurrentMappingKind::DCMK_Host)
-          .Case("device", DoConcurrentMappingKind::DCMK_Device)
-          .Default(std::nullopt);
-
-  if (!val.has_value()) {
-    diags.Report(clang::diag::err_drv_invalid_value)
-        << arg->getAsString(args) << arg->getValue();
-    return false;
-  }
-
-  opts.setDoConcurrentMapping(val.value());
-  return true;
-}
-
-static bool parseVectorLibArg(Fortran::frontend::CodeGenOptions &opts,
-                              llvm::opt::ArgList &args,
-                              clang::DiagnosticsEngine &diags) {
-  llvm::opt::Arg *arg = args.getLastArg(clang::options::OPT_fveclib);
-  if (!arg)
-    return true;
-
-  using VectorLibrary = llvm::driver::VectorLibrary;
-  std::optional<VectorLibrary> val =
-      llvm::StringSwitch<std::optional<VectorLibrary>>(arg->getValue())
-          .Case("Accelerate", VectorLibrary::Accelerate)
-          .Case("libmvec", VectorLibrary::LIBMVEC)
-          .Case("MASSV", VectorLibrary::MASSV)
-          .Case("SVML", VectorLibrary::SVML)
-          .Case("SLEEF", VectorLibrary::SLEEF)
-          .Case("Darwin_libsystem_m", VectorLibrary::Darwin_libsystem_m)
-          .Case("ArmPL", VectorLibrary::ArmPL)
-          .Case("AMDLIBM", VectorLibrary::AMDLIBM)
-          .Case("NoLibrary", VectorLibrary::NoLibrary)
-          .Default(std::nullopt);
-  if (!val.has_value()) {
-    diags.Report(clang::diag::err_drv_invalid_value)
-        << arg->getAsString(args) << arg->getValue();
-    return false;
-  }
-  opts.setVecLib(val.value());
   return true;
 }
 
-// Generate an OptRemark object containing info on if the -Rgroup
-// specified is enabled or not.
-static CodeGenOptions::OptRemark
-parseOptimizationRemark(clang::DiagnosticsEngine &diags,
-                        llvm::opt::ArgList &args, llvm::opt::OptSpecifier optEq,
-                        llvm::StringRef remarkOptName) {
-  assert((remarkOptName == "pass" || remarkOptName == "pass-missed" ||
-          remarkOptName == "pass-analysis") &&
-         "Unsupported remark option name provided.");
-  CodeGenOptions::OptRemark result;
-
-  for (llvm::opt::Arg *a : args) {
-    if (a->getOption().matches(clang::options::OPT_R_Joined)) {
-      llvm::StringRef value = a->getValue();
-
-      if (value == remarkOptName) {
-        result.Kind = CodeGenOptions::RemarkKind::RK_Enabled;
-        // Enable everything
-        result.Pattern = ".*";
-        result.Regex = std::make_shared<llvm::Regex>(result.Pattern);
-
-      } else if (value.split('-') ==
-                 std::make_pair(llvm::StringRef("no"), remarkOptName)) {
-        result.Kind = CodeGenOptions::RemarkKind::RK_Disabled;
-        // Disable everything
-        result.Pattern = "";
-        result.Regex = nullptr;
-      }
-    } else if (a->getOption().matches(optEq)) {
-      result.Kind = CodeGenOptions::RemarkKind::RK_WithPattern;
-      result.Pattern = a->getValue();
-      result.Regex = std::make_shared<llvm::Regex>(result.Pattern);
-      std::string regexError;
-
-      if (!result.Regex->isValid(regexError)) {
-        diags.Report(clang::diag::err_drv_optimization_remark_pattern)
-            << regexError << a->getAsString(args);
-        return CodeGenOptions::OptRemark();
-      }
-    }
-  }
-  return result;
-}
-
 static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
                              llvm::opt::ArgList &args,
                              clang::DiagnosticsEngine &diags) {
   opts.OptimizationLevel = getOptimizationLevel(args, diags);
 
-  if (args.hasFlag(clang::options::OPT_fdebug_pass_manager,
-                   clang::options::OPT_fno_debug_pass_manager, false))
+  if (args.hasFlag(clang::driver::options::OPT_fdebug_pass_manager,
+                   clang::driver::options::OPT_fno_debug_pass_manager, false))
     opts.DebugPassManager = 1;
 
-  if (!args.hasFlag(clang::options::OPT_fprotect_parens,
-                    clang::options::OPT_fno_protect_parens, true))
-    opts.ProtectParens = 0;
-
-  if (args.hasFlag(clang::options::OPT_fstack_arrays,
-                   clang::options::OPT_fno_stack_arrays, false))
+  if (args.hasFlag(clang::driver::options::OPT_fstack_arrays,
+                   clang::driver::options::OPT_fno_stack_arrays, false)) {
     opts.StackArrays = 1;
-
-  if (args.hasFlag(clang::options::OPT_fsafe_trampoline,
-                   clang::options::OPT_fno_safe_trampoline, false))
-    opts.EnableSafeTrampoline = 1;
-
-  if (args.hasFlag(clang::options::OPT_ffp_sum_reassociation,
-                   clang::options::OPT_fno_fp_sum_reassociation, true))
-    opts.SplitSumExpressionTree = 1;
-
-  // Match the LLVM pipeline default (PipelineTuningOptions::LoopInterchange),
-  // which enables the pass whenever the optimization pipeline runs.
-  opts.InterchangeLoops =
-      args.hasFlag(clang::options::OPT_floop_interchange,
-                   clang::options::OPT_fno_loop_interchange, true);
-
-  if (args.hasArg(clang::options::OPT_funique_internal_linkage_names))
-    opts.UniqueInternalLinkageNames = 1;
-
-  if (args.getLastArg(clang::options::OPT_fexperimental_loop_fusion))
-    opts.FuseLoops = 1;
-
-  if (args.getLastArg(clang::options::OPT_vectorize_loops))
-    opts.VectorizeLoop = 1;
-
-  if (args.getLastArg(clang::options::OPT_vectorize_slp))
-    opts.VectorizeSLP = 1;
-
-  if (args.hasFlag(clang::options::OPT_floop_versioning,
-                   clang::options::OPT_fno_loop_versioning, false))
+  }
+  if (args.hasFlag(clang::driver::options::OPT_floop_versioning,
+                   clang::driver::options::OPT_fno_loop_versioning, false)) {
     opts.LoopVersioning = 1;
-
-  if (args.hasFlag(clang::options::OPT_floop_tripcount_versioning,
-                   clang::options::OPT_fno_loop_tripcount_versioning, false))
-    opts.LoopTripCountVersioning = 1;
-
-  opts.UnrollLoops = args.hasFlag(clang::options::OPT_funroll_loops,
-                                  clang::options::OPT_fno_unroll_loops,
-                                  (opts.OptimizationLevel > 1));
-
-  opts.AliasAnalysis = opts.OptimizationLevel > 0;
-
-  // -mframe-pointer=none/non-leaf/reserved/all option.
-  if (const llvm::opt::Arg *a =
-          args.getLastArg(clang::options::OPT_mframe_pointer_EQ)) {
-    std::optional<llvm::FramePointerKind> val =
-        llvm::StringSwitch<std::optional<llvm::FramePointerKind>>(a->getValue())
-            .Case("none", llvm::FramePointerKind::None)
-            .Case("non-leaf", llvm::FramePointerKind::NonLeaf)
-            .Case("non-leaf-no-reserve",
-                  llvm::FramePointerKind::NonLeafNoReserve)
-            .Case("reserved", llvm::FramePointerKind::Reserved)
-            .Case("all", llvm::FramePointerKind::All)
-            .Default(std::nullopt);
-
-    if (!val.has_value()) {
-      diags.Report(clang::diag::err_drv_invalid_value)
-          << a->getAsString(args) << a->getValue();
-    } else
-      opts.setFramePointer(val.value());
   }
 
-  for (auto *a : args.filtered(clang::options::OPT_fpass_plugin_EQ))
+  for (auto *a : args.filtered(clang::driver::options::OPT_fpass_plugin_EQ))
     opts.LLVMPassPlugins.push_back(a->getValue());
 
-  opts.Reciprocals = clang::parseMRecipOption(diags, args);
-
-  opts.PreferVectorWidth = clang::parseMPreferVectorWidthOption(diags, args);
-
   // -fembed-offload-object option
-  for (auto *a : args.filtered(clang::options::OPT_fembed_offload_object_EQ))
+  for (auto *a :
+       args.filtered(clang::driver::options::OPT_fembed_offload_object_EQ))
     opts.OffloadObjects.push_back(a->getValue());
 
-  if (args.hasArg(clang::options::OPT_finstrument_functions))
-    opts.InstrumentFunctions = 1;
-
-  if (args.hasArg(clang::options::OPT_fno_optimize_sibling_calls))
-    opts.DisableTailCalls = 1;
-
-  // -fno-integrated-as: emit GNU Assembler compatible assembly.
-  if (!args.hasFlag(clang::options::OPT_fintegrated_as,
-                    clang::options::OPT_fno_integrated_as, true))
-    opts.DisableIntegratedAS = 1;
-
-  opts.FunctionSections =
-      args.hasFlag(clang::options::OPT_ffunction_sections,
-                   clang::options::OPT_fno_function_sections,
-                   /*Default=*/false);
-  opts.DataSections = args.hasFlag(clang::options::OPT_fdata_sections,
-                                   clang::options::OPT_fno_data_sections,
-                                   /*Default=*/false);
-
+  // -flto=full/thin option.
   if (const llvm::opt::Arg *a =
-          args.getLastArg(clang::options::OPT_mcode_object_version_EQ)) {
+          args.getLastArg(clang::driver::options::OPT_flto_EQ)) {
     llvm::StringRef s = a->getValue();
-    if (s == "6")
-      opts.CodeObjectVersion = llvm::CodeObjectVersionKind::COV_6;
-    if (s == "5")
-      opts.CodeObjectVersion = llvm::CodeObjectVersionKind::COV_5;
-    if (s == "4")
-      opts.CodeObjectVersion = llvm::CodeObjectVersionKind::COV_4;
-    if (s == "none")
-      opts.CodeObjectVersion = llvm::CodeObjectVersionKind::COV_None;
-  }
-
-  // -f[no-]save-optimization-record[=<format>]
-  if (const llvm::opt::Arg *a =
-          args.getLastArg(clang::options::OPT_opt_record_file))
-    opts.OptRecordFile = a->getValue();
-
-  // Optimization file format. Defaults to yaml
-  if (const llvm::opt::Arg *a =
-          args.getLastArg(clang::options::OPT_opt_record_format))
-    opts.OptRecordFormat = a->getValue();
-
-  // Specifies, using a regex, which successful optimization passes(middle and
-  // backend), to include in the final optimization record file generated. If
-  // not provided -fsave-optimization-record will include all passes.
-  if (const llvm::opt::Arg *a =
-          args.getLastArg(clang::options::OPT_opt_record_passes))
-    opts.OptRecordPasses = a->getValue();
-
-  // Create OptRemark that allows printing of all successful optimization
-  // passes applied.
-  opts.OptimizationRemark =
-      parseOptimizationRemark(diags, args, clang::options::OPT_Rpass_EQ,
-                              /*remarkOptName=*/"pass");
-
-  // Create OptRemark that allows all missed optimization passes to be printed.
-  opts.OptimizationRemarkMissed =
-      parseOptimizationRemark(diags, args, clang::options::OPT_Rpass_missed_EQ,
-                              /*remarkOptName=*/"pass-missed");
-
-  // Create OptRemark that allows all optimization decisions made by LLVM
-  // to be printed.
-  opts.OptimizationRemarkAnalysis = parseOptimizationRemark(
-      diags, args, clang::options::OPT_Rpass_analysis_EQ,
-      /*remarkOptName=*/"pass-analysis");
-
-  if (opts.getDebugInfo() == llvm::codegenoptions::NoDebugInfo) {
-    // If the user requested a flag that requires source locations available in
-    // the backend, make sure that the backend tracks source location
-    // information.
-    bool needLocTracking = !opts.OptRecordFile.empty() ||
-                           !opts.OptRecordPasses.empty() ||
-                           !opts.OptRecordFormat.empty() ||
-                           opts.OptimizationRemark.hasValidPattern() ||
-                           opts.OptimizationRemarkMissed.hasValidPattern() ||
-                           opts.OptimizationRemarkAnalysis.hasValidPattern();
-
-    if (needLocTracking)
-      opts.setDebugInfo(llvm::codegenoptions::LocTrackingOnly);
+    assert((s == "full" || s == "thin") && "Unknown LTO mode.");
+    if (s == "full")
+      opts.PrepareForFullLTO = true;
+    else
+      opts.PrepareForThinLTO = true;
   }
 
-  if (auto *a = args.getLastArg(clang::options::OPT_save_temps_EQ))
+  if (auto *a = args.getLastArg(clang::driver::options::OPT_save_temps_EQ))
     opts.SaveTempsDir = a->getValue();
 
-  // -record-command-line option.
-  if (const llvm::opt::Arg *a =
-          args.getLastArg(clang::options::OPT_record_command_line)) {
-    opts.RecordCommandLine = a->getValue();
-  }
-
-  // -mlink-builtin-bitcode
-  for (auto *a : args.filtered(clang::options::OPT_mlink_builtin_bitcode))
-    opts.BuiltinBCLibs.push_back(a->getValue());
-
   // -mrelocation-model option.
   if ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/235472


More information about the flang-commits mailing list