[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