[flang-commits] [clang] [flang] [flang] Fix compiler invocation issue (#232487) (PR #235473)
via flang-commits
flang-commits at lists.llvm.org
Sun Oct 25 08:51:14 PDT 2026
https://github.com/Harshit2906 created https://github.com/llvm/llvm-project/pull/235473
Fixes #232487
>From 00c96d9f2ad2cf9ef6337a922ec6b54fe8939fb0 Mon Sep 17 00:00:00 2001
From: Harshit <harshitjhiraparaharshit at gmail.com>
Date: Sun, 25 Oct 2026 21:04:57 +0530
Subject: [PATCH] [flang] Fix compiler invocation issue (#232487)
---
.../clang/Basic/DiagnosticDriverKinds.td | 357 +---
flang/lib/Frontend/CompilerInvocation.cpp | 1751 ++++-------------
2 files changed, 416 insertions(+), 1692 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 79859e724a8179..f04e199b46fe17 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -20,8 +20,6 @@ def err_drv_unsupported_opt_for_language_mode : Error<
"unsupported option '%0' for language mode '%1'">;
def err_drv_unsupported_option_argument : Error<
"unsupported argument '%1' to option '%0'">;
-def err_drv_unsupported_option_argument_for_target : Error<
- "unsupported argument '%1' to option '%0' for target '%2'">;
def err_drv_unknown_stdin_type : Error<
"-E or -x required when input is from standard input">;
def err_drv_unknown_stdin_type_clang_cl : Error<
@@ -33,13 +31,12 @@ def err_drv_invalid_riscv_arch_name : Error<
"invalid arch name '%0', %1">;
def err_drv_invalid_riscv_cpu_name_for_target : Error<
"cpu '%0' does not support rv%select{32|64}1">;
-def err_drv_invalid_riscv_mtune_string : Error<
- "invalid %select{-mtune|tune feature}0 string '%1': %2">;
def warn_drv_invalid_arch_name_with_suggestion : Warning<
"ignoring invalid /arch: argument '%0'; for %select{64|32}1-bit expected one of %2">,
InGroup<UnusedCommandLineArgument>;
def warn_drv_avr_mcu_not_specified : Warning<
- "no target microcontroller specified, please pass -mmcu=<mcu name>">,
+ "no target microcontroller specified on command line, cannot "
+ "link standard libraries, please pass -mmcu=<mcu name>">,
InGroup<AVRRtlibLinkingQuirks>;
def warn_drv_avr_libc_not_found: Warning<
"no avr-libc installation can be found on the system, "
@@ -58,8 +55,6 @@ def warn_drv_avr_stdlib_not_linked: Warning<
InGroup<AVRRtlibLinkingQuirks>;
def err_drv_cuda_bad_gpu_arch : Error<"unsupported CUDA gpu architecture: %0">;
def err_drv_offload_bad_gpu_arch : Error<"unsupported %0 gpu architecture: %1">;
-def err_drv_offload_missing_gpu_arch : Error<
- "must pass in an explicit %0 gpu architecture to '%1'">;
def err_drv_no_cuda_installation : Error<
"cannot find CUDA installation; provide its path via '--cuda-path', or pass "
"'-nocudainc' to build without CUDA includes">;
@@ -69,51 +64,24 @@ def err_drv_no_cuda_libdevice : Error<
"libdevice">;
def err_drv_no_rocm_device_lib : Error<
- "cannot find ROCm device library%select{| for %1| for ABI version %1"
- "%select{|, which requires ROCm %3 or higher}2}0; provide its path via "
+ "cannot find ROCm device library%select{| for %1|for ABI version %1}0; provide its path via "
"'--rocm-path' or '--rocm-device-lib-path', or pass '-nogpulib' to build "
"without ROCm device library">;
def err_drv_no_hip_runtime : Error<
"cannot find HIP runtime; provide its path via '--rocm-path', or pass "
"'-nogpuinc' to build without HIP runtime">;
-def err_drv_no_hipstdpar_lib : Error<
- "cannot find HIP Standard Parallelism Acceleration library; provide it via "
- "'--hipstdpar-path'">;
-def err_drv_no_hipstdpar_thrust_lib : Error<
- "cannot find rocThrust, which is required by the HIP Standard Parallelism "
- "Acceleration library; provide it via "
- "'--hipstdpar-thrust-path'">;
-def err_drv_no_hipstdpar_prim_lib : Error<
- "cannot find rocPrim, which is required by the HIP Standard Parallelism "
- "Acceleration library; provide it via '--hipstdpar-prim-path'">;
def err_drv_no_hipspv_device_lib : Error<
"cannot find HIP device library%select{| for %1}0; provide its path via "
"'--hip-path' or '--hip-device-lib-path', or pass '-nogpulib' to build "
"without HIP device library">;
def err_drv_hipspv_no_hip_path : Error<
- "'--hip-path' must be specified when offloading to SPIR-V unless '-nogpuinc' "
- "is given">;
-
-def err_drv_sycl_no_rdc_multiple_targets : Error<
- "'%0' is not supported with multiple SYCL offloading targets">;
-
-// SYCL Windows-specific diagnostics
-def err_drv_sycl_requires_dynamic_crt : Error<
- "SYCL requires dynamic C++ runtime (/MD or /MDd); "
- "static C++ runtime (/MT or /MTd) is not supported">;
-
-def err_drv_no_spv_tools : Error<"cannot find SPIR-V Tools binary '%0', which "
- "is required for SPIR-V compilation. "
- "It can be obtained from your system package "
- "manager or from KhronosGroup/SPIRV-Tools "
- "on GitHub">;
+ "'--hip-path' must be specified when offloading to "
+ "SPIR-V%select{| unless %1 is given}0.">;
def err_drv_undetermined_gpu_arch : Error<
- "cannot determine %0 architecture: %1; consider passing it via '%2'; "
- "environment variable CLANG_TOOLCHAIN_PROGRAM_TIMEOUT specifies the tool "
- "timeout (integer secs, <=0 is infinite)">;
-
+ "cannot determine %0 architecture: %1; consider passing it via "
+ "'%2'">;
def warn_drv_multi_gpu_arch : Warning<
"multiple %0 architectures are detected: %1; only the first one is used for "
"'%2'">, InGroup<MultiGPU>;
@@ -132,8 +100,6 @@ def err_drv_cuda_host_arch : Error<
"unsupported architecture '%0' for host compilation">;
def err_drv_mix_cuda_hip : Error<
"mixed CUDA and HIP compilation is not supported">;
-def err_drv_mix_offload : Error<
- "mixed %0 and %1 offloading compilation is not supported">;
def err_drv_bad_target_id : Error<
"invalid target ID '%0'; format is a processor name followed by an optional "
"colon-delimited list of features followed by an enable/disable sign (e.g., "
@@ -142,9 +108,6 @@ def err_drv_bad_offload_arch_combo : Error<
"invalid offload arch combinations: '%0' and '%1' (for a specific processor, "
"a feature should either exist in all offload archs, or not exist in any "
"offload archs)">;
-def err_drv_unsupported_option_for_offload_arch_req_feature : Error<
- "'%0' option for offload arch '%1' is not currently supported "
- "there. Use it with an offload arch containing '%2' instead">;
def warn_drv_unsupported_option_for_offload_arch_req_feature : Warning<
"ignoring '%0' option for offload arch '%1' as it is not currently supported "
"there. Use it with an offload arch containing '%2' instead">,
@@ -152,43 +115,16 @@ def warn_drv_unsupported_option_for_offload_arch_req_feature : Warning<
def warn_drv_unsupported_option_for_target : Warning<
"ignoring '%0' option as it is not currently supported for target '%1'">,
InGroup<OptionIgnored>;
-def err_drv_unsupported_option_for_target : Error<
- "'%0' option is not currently supported for target '%1'">;
-def warn_drv_unsupported_option_part_for_target : Warning<
- "ignoring '%0' in '%1' option as it is not currently supported for target '%2'">,
- InGroup<OptionIgnored>;
-def err_drv_unsupported_option_part_for_target : Error<
- "'%0' in '%1' option is not currently supported for target '%2'">;
-def warn_drv_invalid_argument_for_flang : Warning<
- "'%0' is not valid for Fortran">,
- InGroup<OptionIgnored>;
def warn_drv_unsupported_option_for_flang : Warning<
"the argument '%0' is not supported for option '%1'. Mapping to '%1%2'">,
InGroup<OptionIgnored>;
def warn_drv_unsupported_diag_option_for_flang : Warning<
- "the warning option '-%0' is not supported">,
+ "The warning option '-%0' is not supported">,
InGroup<OptionIgnored>;
def warn_drv_unsupported_option_for_processor : Warning<
"ignoring '%0' option as it is not currently supported for processor '%1'">,
InGroup<OptionIgnored>;
-def warn_drv_unsupported_option_for_runtime : Warning<
- "ignoring '%0' option as it is not currently supported for runtime '%1'">,
- InGroup<OptionIgnored>;
-def warn_drv_hexagon_reserved_caller_saved_reg : Warning<
- "reserving the caller-saved register '%0' may lead to incorrect code if it "
- "is not also reserved in all other translation units and libraries; you are "
- "responsible for ensuring the register is managed consistently">,
- InGroup<DiagGroup<"hexagon-reserved-caller-saved">>;
-def warn_drv_unsupported_openmp_library : Warning<
- "the library '%0=%1' is not supported, OpenMP will not be enabled">,
- InGroup<OptionIgnored>;
-def warn_openmp_impl_incomplete : Warning<
- "OpenMP support for version %0 in flang is still incomplete">,
- InGroup<ExperimentalOption>;
-def warn_openmp_spec_incomplete : Warning<
- "the specification for OpenMP version %0 is still under development; "
- "the syntax and semantics of new features may be subject to change">,
- InGroup<ExperimentalOption>;
+
def err_drv_invalid_thread_model_for_target : Error<
"invalid thread model '%0' in '%1' for this target">;
def err_drv_invalid_linker_name : Error<
@@ -199,14 +135,10 @@ def err_drv_unsupported_rtlib_for_platform : Error<
"unsupported runtime library '%0' for platform '%1'">;
def err_drv_invalid_unwindlib_name : Error<
"invalid unwind library name in argument '%0'">;
-def err_drv_unsupported_unwind_for_platform : Error<
- "unsupported unwind library '%0' for platform '%1'">;
def err_drv_incompatible_unwindlib : Error<
"--rtlib=libgcc requires --unwindlib=libgcc">;
def err_drv_incompatible_options : Error<
"the combination of '%0' and '%1' is incompatible">;
-def err_drv_invalid_cstdlib_name : Error<
- "invalid C library name in argument '%0'">;
def err_drv_invalid_stdlib_name : Error<
"invalid library name in argument '%0'">;
def err_drv_invalid_output_with_multiple_archs : Error<
@@ -240,26 +172,16 @@ def err_drv_invalid_Xopenmp_target_with_args : Error<
"invalid -Xopenmp-target argument: '%0', options requiring arguments are unsupported">;
def err_drv_argument_only_allowed_with : Error<
"invalid argument '%0' only allowed with '%1'">;
-def err_drv_opt_unsupported_input_type : Error<
- "'%0' invalid for input of type %1">;
+def err_drv_minws_unsupported_input_type : Error<
+ "'-fminimize-whitespace' invalid for input of type %0">;
def err_drv_amdgpu_ieee_without_no_honor_nans : Error<
"invalid argument '-mno-amdgpu-ieee' only allowed with relaxed NaN handling">;
def err_drv_argument_not_allowed_with : Error<
"invalid argument '%0' not allowed with '%1'">;
-def warn_drv_argument_not_allowed_with : Warning<
- "invalid argument '%0' not allowed with '%1'">,
- InGroup<OptionIgnored>;
-def err_drv_sycl_requires_cxx17 : Error<
- "SYCL requires C++17 or later; '%0' is not supported">;
def err_drv_cannot_open_randomize_layout_seed_file : Error<
"cannot read randomize layout seed file '%0'">;
def err_drv_invalid_version_number : Error<
"invalid version number in '%0'">;
-def err_drv_invalid_version_number_inferred
- : Error<"invalid version number '%0' inferred from '%1'">;
-def err_drv_missing_version_number : Error<"missing version number in '%0'">;
-def err_drv_kcfi_arity_unsupported_target : Error<
- "target '%0' is unsupported by -fsanitize-kcfi-arity">;
def err_drv_no_linker_llvm_support : Error<
"'%0': unable to pass LLVM bit-code files to linker">;
def err_drv_no_ast_support : Error<
@@ -328,11 +250,6 @@ def err_cpu_unsupported_isa
def err_arch_unsupported_isa
: Error<"architecture '%0' does not support '%1' execution mode">;
-def err_zos_target_release_discontinued
- : Error<"z/OS target level \"%0\" is discontinued">;
-def err_zos_target_unrecognized_release
- : Error<"z/OS target level \"%0\" is invalid">;
-
def err_drv_I_dash_not_supported : Error<
"'%0' not supported, please use -iquote instead">;
def err_drv_unknown_argument : Error<"unknown argument: '%0'">;
@@ -356,12 +273,8 @@ def warn_drv_yc_multiple_inputs_clang_cl : Warning<
def warn_drv_potentially_misspelled_joined_argument : Warning<
"joined argument treated as '%0'; did you mean '%1'?">, InGroup<UnknownArgument>;
-def err_drv_too_many_actions: Error<
- "only one action option is allowed. Got %0">;
def err_drv_invalid_value : Error<"invalid value '%1' in '%0'">;
def err_drv_invalid_int_value : Error<"invalid integral value '%1' in '%0'">;
-def err_drv_invalid_escaped_command_line
- : Error<"invalid escaped command line: %0">;
def err_drv_invalid_value_with_suggestion : Error<
"invalid value '%1' in '%0', expected one of: %2">;
def err_drv_alignment_not_power_of_two : Error<"alignment is not a power of 2 in '%0'">;
@@ -412,11 +325,9 @@ def err_drv_optimization_remark_format : Error<
def err_drv_no_neon_modifier : Error<"[no]neon is not accepted as modifier, please use [no]simd instead">;
def err_drv_invalid_omp_target : Error<"OpenMP target is invalid: '%0'">;
def err_drv_incompatible_omp_arch : Error<"OpenMP target architecture '%0' pointer size is incompatible with host '%1'">;
-def err_drv_dyndbg_lto : Error<"'-fdynamic-debugging' incompatible with '-flto'">;
-def err_drv_dyndbg_incompatible : Error<"'-fdynamic-debugging' incompatible with '%0'">;
-def err_drv_dyndbg_ir : Error<"'-fdynamic-debugging' incompatible with IR input">;
-def warn_drv_dyndbg_req_debug : Warning<"'-fdynamic-debugging' ignored: requires debug info">,
- InGroup<DynamicDebugging>;
+def err_drv_omp_host_ir_file_not_found : Error<
+ "provided host compiler IR file '%0' is required to generate code for OpenMP "
+ "target regions but cannot be found">;
def err_drv_omp_host_target_not_supported : Error<
"target '%0' is not a supported OpenMP host target">;
def err_drv_expecting_fopenmp_with_fopenmp_targets : Error<
@@ -424,7 +335,7 @@ def err_drv_expecting_fopenmp_with_fopenmp_targets : Error<
"compatible with offloading; e.g., '-fopenmp=libomp' or '-fopenmp=libiomp5'">;
def err_drv_failed_to_deduce_target_from_arch : Error<
"failed to deduce triple for target architecture '%0'; specify the triple "
- "using '-fopenmp-targets' and '-Xopenmp-target' instead">;
+ "using '-fopenmp-targets' and '-Xopenmp-target' instead.">;
def err_drv_omp_offload_target_missingbcruntime : Error<
"no library '%0' found in the default clang lib directory or in LIBRARY_PATH"
"; use '--libomptarget-%1-bc-path' to specify %1 bitcode library">;
@@ -444,13 +355,8 @@ def err_drv_negative_columns : Error<
def err_drv_small_columns : Error<
"invalid value '%1' in '%0', value must be '%2' or greater">;
def err_drv_large_columns : Error<
- "invalid value '%1' in '%0', value must be '%2' or smaller">;
-def warn_drv_fraw_string_literals_in_cxx11 : Warning<
- "ignoring '-f%select{no-|}0raw-string-literals', which is only valid for C and C++ standards before C++11">,
- InGroup<UnusedCommandLineArgument>;
-
-def err_drv_libclc_not_found : Error<"no libclc library '%0' found in the clang resource directory">;
-
+ "invalid value '%1' in '%0', value must be '2147483647' or smaller">;
+
def err_drv_invalid_malign_branch_EQ : Error<
"invalid argument '%0' to -malign-branch=; each element must be one of: %1">;
@@ -458,14 +364,8 @@ def err_drv_print_header_env_var : Error<
"environment variable CC_PRINT_HEADERS_%select{FORMAT|FILTERING}0 has invalid value %1">;
def err_drv_print_header_env_var_combination : Error<
"unsupported combination: CC_PRINT_HEADERS_FORMAT=%0 and CC_PRINT_HEADERS_FILTERING=%1">;
-def err_drv_print_header_env_var_invalid_format : Error<
- "environment variable CC_PRINT_HEADERS_FORMAT=%0 requires a compatible value for CC_PRINT_HEADERS_FILTERING">;
-def err_drv_print_header_cc1_invalid_combination : Error<
+def err_drv_print_header_env_var_combination_cc1 : Error<
"unsupported combination: -header-include-format=%0 and -header-include-filtering=%1">;
-def err_drv_print_header_cc1_invalid_filtering : Error<
- "-header-include-filtering=%0 requires a compatible value for -header-include-format">;
-def err_drv_print_header_cc1_invalid_format : Error<
- "-header-include-format=%0 requires a compatible value for -header-include-filtering">;
def warn_O4_is_O3 : Warning<"-O4 is equivalent to -O3">, InGroup<Deprecated>;
def warn_drv_optimization_value : Warning<"optimization level '%0' is not supported; using '%1%2' instead">,
@@ -477,9 +377,6 @@ def warn_ignored_clang_option : Warning<"the flag '%0' has been deprecated and w
def warn_drv_unsupported_opt_for_target : Warning<
"optimization flag '%0' is not supported for target '%1'">,
InGroup<IgnoredOptimizationArgument>;
-def warn_drv_riscv_be_experimental : Warning<
- "big-endian RISC-V target support is experimental">,
- InGroup<RISCVBEExperimental>;
def warn_drv_unsupported_debug_info_opt_for_target : Warning<
"debug information option '%0' is not supported for target '%1'">,
InGroup<UnsupportedTargetOpt>;
@@ -489,6 +386,9 @@ def warn_drv_dwarf_version_limited_by_target : Warning<
InGroup<UnsupportedTargetOpt>;
def warn_c_kext : Warning<
"ignoring -fapple-kext which is valid for C++ and Objective-C++ only">;
+def warn_ignoring_fdiscard_for_bitcode : Warning<
+ "ignoring -fdiscard-value-names for LLVM Bitcode">,
+ InGroup<UnusedCommandLineArgument>;
def warn_drv_input_file_unused : Warning<
"%0: '%1' input unused%select{ when '%3' is present|}2">,
InGroup<UnusedCommandLineArgument>;
@@ -516,17 +416,7 @@ def warn_drv_diagnostics_misexpect_requires_pgo : Warning<
def warn_drv_clang_unsupported : Warning<
"the clang compiler does not support '%0'">;
def warn_drv_deprecated_arg : Warning<
- "argument '%0' is deprecated%select{|, use '%2' instead}1">, InGroup<Deprecated>;
-def warn_drv_deprecated_arg_ofast : Warning<
- "argument '-Ofast' is deprecated; use '-O3' to enable only conforming optimizations, "
- "or consult the documentation for the same behavior">,
- InGroup<DeprecatedOFast>;
-def warn_drv_deprecated_arg_ofast_for_flang : Warning<
- "argument '-Ofast' is deprecated; use '-O3 -ffast-math -fstack-arrays -fno-protect-parens' for the same behavior,"
- " or '-O3 -fstack-arrays' to enable only conforming optimizations">,
- InGroup<DeprecatedOFast>;
-def warn_drv_deprecated_custom : Warning<
- "argument '%0' is deprecated, %1">, InGroup<Deprecated>;
+ "argument '%0' is deprecated, use '%1' instead">, InGroup<Deprecated>;
def warn_drv_assuming_mfloat_abi_is : Warning<
"unknown platform, assuming -mfloat-abi=%0">;
def warn_drv_unsupported_float_abi_by_lib : Warning<
@@ -537,34 +427,20 @@ def warn_drv_no_floating_point_registers: Warning<
InGroup<UnsupportedABI>;
def warn_ignoring_ftabstop_value : Warning<
"ignoring invalid -ftabstop value '%0', using default value %1">;
-def warn_drv_overriding_option : Warning<
+def warn_drv_overriding_flag_option : Warning<
"overriding '%0' option with '%1'">,
- InGroup<DiagGroup<"overriding-option">>;
-def warn_drv_overriding_deployment_version
- : Warning<"overriding deployment version from '%0' to '%1'">,
- InGroup<DiagGroup<"overriding-deployment-version">>;
-def warn_drv_overriding_complex_range : Warning<
- "'%1' sets complex range to \"%3\" overriding the setting of \"%2\" that was implied by '%0'">,
- InGroup<DiagGroup<"overriding-complex-range">>;
+ InGroup<DiagGroup<"overriding-t-option">>;
def warn_drv_treating_input_as_cxx : Warning<
"treating '%0' input as '%1' when in C++ mode, this behavior is deprecated">,
InGroup<Deprecated>;
def warn_drv_pch_not_first_include : Warning<
"precompiled header '%0' was ignored because '%1' is not first '-include'">;
-def warn_drv_pch_ignoring_gch_file : Warning<
- "precompiled header '%0' was ignored because it is not a clang PCH file">,
- InGroup<IgnoredGCH>;
-def warn_drv_pch_ignoring_gch_dir : Warning<
- "precompiled header directory '%0' was ignored because it contains no clang PCH files">,
- InGroup<IgnoredGCH>;
def warn_missing_sysroot : Warning<"no such sysroot directory: '%0'">,
InGroup<DiagGroup<"missing-sysroot">>;
def warn_incompatible_sysroot : Warning<"using sysroot for '%0' but targeting '%1'">,
InGroup<DiagGroup<"incompatible-sysroot">>;
def warn_debug_compression_unavailable : Warning<"cannot compress debug sections (%0 not enabled)">,
InGroup<DiagGroup<"debug-compression-unavailable">>;
-def err_drv_time_trace_compression_unavailable
- : Error<"cannot compress time trace (%0 not enabled)">;
def warn_drv_disabling_vptr_no_rtti_default : Warning<
"implicitly disabling vptr sanitizer because rtti wasn't enabled">,
InGroup<AutoDisableVptrSanitizer>;
@@ -577,17 +453,8 @@ def warn_ignoring_verify_debuginfo_preserve_export : Warning<
InGroup<UnusedCommandLineArgument>;
def warn_unsupported_branch_protection: Warning <
"invalid branch protection option '%0' in '%1'">, InGroup<BranchProtection>;
-def warn_harden_pac_ret_requires_pac_ret: Warning<
- "ignoring '-mharden-pac-ret' as it requires return address signing">, InGroup<UnusedCommandLineArgument>;
def err_sls_hardening_arm_not_supported : Error<
"-mharden-sls is only supported on armv7-a or later">;
-def warn_drv_large_data_threshold_invalid_code_model: Warning<
- "'%0' only applies to medium and large code models">,
- InGroup<UnusedCommandLineArgument>;
-def warn_drv_math_errno_enabled_after_veclib: Warning<
- "math errno enabled by '%0' after it was implicitly disabled by '%1',"
- " this may limit the utilization of the vector library">,
- InGroup<MathErrnoEnabledWithVecLib>;
def note_drv_command_failed_diag_msg : Note<
"diagnostic msg: %0">;
@@ -613,8 +480,16 @@ def err_analyzer_checker_option_invalid_input : Error<
def err_analyzer_checker_incompatible_analyzer_option : Error<
"checker cannot be enabled with analyzer option '%0' == %1">;
def err_analyzer_not_built_with_z3 : Error<
- "analyzer constraint manager 'unsupported-z3' is only available if LLVM was "
- "built with -DLLVM_ENABLE_Z3_SOLVER=ON">;
+ "analyzer constraint manager 'z3' is only available if LLVM was built with "
+ "-DLLVM_ENABLE_Z3_SOLVER=ON">;
+def warn_analyzer_deprecated_option : Warning<
+ "analyzer option '%0' is deprecated. This flag will be removed in %1, and "
+ "passing this option will be an error.">,
+ InGroup<DeprecatedStaticAnalyzerFlag>;
+def warn_analyzer_deprecated_option_with_alternative : Warning<
+ "analyzer option '%0' is deprecated. This flag will be removed in %1, and "
+ "passing this option will be an error. Use '%2' instead.">,
+ InGroup<DeprecatedStaticAnalyzerFlag>;
def warn_drv_needs_hvx : Warning<
"%0 requires HVX, use -mhvx/-mhvx= to enable it">,
@@ -636,63 +511,12 @@ def err_test_module_file_extension_format : Error<
"'blockname:major:minor:hashed:user info'">;
def err_drv_module_output_with_multiple_arch : Error<
- "option '-fmodule-output' cannot be used with multiple arch options">;
-
-def err_drv_reduced_module_output_overrided : Warning<
- "the implicit output of reduced BMI may be overrided by the output file specified by '--precompile'. "
- "please consider use '-fmodule-output=' to specify the output file for reduced BMI explicitly">,
- InGroup<DiagGroup<"reduced-bmi-output-overrided">>;
-
-def err_drv_modules_driver_requires_reduced_bmi : Error<
- "'-fmodules-driver' is currently incompatible with '-fno-modules-reduced-bmi'">;
-def remark_performing_driver_managed_module_build : Remark<
- "performing driver managed module build">, InGroup<ModulesDriver>;
-def remark_modules_manifest_not_found : Remark<
- "standard modules manifest file not found; import of standard library "
- "modules not supported">,
- InGroup<ModulesDriver>;
-def remark_using_modules_manifest : Remark<
- "using standard modules manifest file '%0'">,
- InGroup<ModulesDriver>;
-def err_modules_manifest_failed_parse : Error<
- "failure while parsing standard modules manifest: '%0'">;
-def err_default_modules_cache_not_available : Error<
- "unable to determine the default -fmodules-cache-path. Please specify it "
- "explicitly using -fmodules-cache-path or the CLANG_MODULE_CACHE_PATH "
- "environment variable">;
-def err_dependency_scan_failed : Error<
- "failed to perform dependency scan">;
-def err_modules_driver_named_module_redefinition : Error<
- "duplicate definitions of C++20 named module '%0' in '%1' and '%2'">;
-def remark_printing_module_graph : Remark<
- "printing module dependency graph">,
- InGroup<ModulesDriver>;
-def err_module_defined_outside_of_module_source : Error<
- "module '%0' is defined in file '%1', but module declarations are only "
- "allowed in C++ module inputs; use the '.cppm' extension or '-x c++module'">;
-def err_drv_depscan_log_path_empty : Error<
- "'-fdepscan-log-path=' requires a non-empty file path">;
-def err_drv_depscan_log_path_inconsistent : Error<
- "'-fdepscan-log-path' set inconsistently within a dependency scan: "
- "%select{no log path|log path '%1'}0 conflicts with "
- "%select{no log path|log path '%3'}2 requested earlier">;
-
-def warn_drv_delayed_template_parsing_after_cxx20 : Warning<
- "-fdelayed-template-parsing is deprecated after C++20">,
- InGroup<DiagGroup<"delayed-template-parsing-in-cxx20">>;
+ "option '-fmodule-output' can't be used with multiple arch options">;
def err_drv_extract_api_wrong_kind : Error<
"header file '%0' input '%1' does not match the type of prior input "
"in api extraction; use '-x %2' to override">;
-def err_drv_missing_symbol_graph_dir: Error<
- "must provide a symbol graph output directory using "
- "'--symbol-graph-dir=<directory>'">;
-
-def err_drv_unexpected_symbol_graph_output : Error<
- "unexpected output symbol graph '%1'; please provide "
- "'--symbol-graph-dir=<directory>' instead">;
-
def warn_slash_u_filename : Warning<"'/U%0' treated as the '/U' option">,
InGroup<DiagGroup<"slash-u-filename">>;
def note_use_dashdash : Note<
@@ -732,6 +556,9 @@ def warn_drv_unsupported_gpopt : Warning<
"ignoring '-mgpopt' option as it cannot be used with %select{|the implicit"
" usage of }0-mabicalls">,
InGroup<UnsupportedGPOpt>;
+def warn_drv_unsupported_sdata : Warning<
+ "ignoring '-msmall-data-limit=' with -mcmodel=large for -fpic or RV64">,
+ InGroup<OptionIgnored>;
def warn_drv_unsupported_longcalls : Warning<
"ignoring '-mlong-calls' option as it is not currently supported with "
"%select{|the implicit usage of }0-mabicalls">,
@@ -772,17 +599,10 @@ def warn_drv_fine_grained_bitfield_accesses_ignored : Warning<
"option '-ffine-grained-bitfield-accesses' cannot be enabled together with a sanitizer; flag ignored">,
InGroup<OptionIgnored>;
-def err_drv_profile_instrument_use_path_with_no_kind : Error<
- "option '-fprofile-instrument-use-path=' requires -fprofile-instrument-use=<kind>">;
-
def note_drv_verify_prefix_spelling : Note<
"-verify prefixes must start with a letter and contain only alphanumeric"
" characters, hyphens, and underscores">;
-def note_command_line_code_loc_requirement
- : Note<"-code-completion-at=<file>:<line>:<column> requires <line> and "
- "<column> to be integers greater than zero">;
-
def warn_drv_global_isel_incomplete : Warning<
"-fglobal-isel support for the '%0' architecture is incomplete">,
InGroup<GlobalISel>;
@@ -803,7 +623,6 @@ def warn_drv_darwin_sdk_invalid_settings : Warning<
"SDK settings were ignored as 'SDKSettings.json' could not be parsed">,
InGroup<DiagGroup<"darwin-sdk-settings">>;
-def err_missing_sysroot : Error<"no such sysroot directory: '%0'">;
def err_drv_darwin_sdk_missing_arclite : Error<
"SDK does not contain 'libarclite' at the path '%0'; try increasing the minimum deployment target">;
@@ -814,13 +633,6 @@ def err_drv_trivial_auto_var_init_stop_after_missing_dependency : Error<
def err_drv_trivial_auto_var_init_stop_after_invalid_value : Error<
"'-ftrivial-auto-var-init-stop-after=*' only accepts positive integers">;
-def err_drv_trivial_auto_var_init_max_size_missing_dependency : Error<
- "'-ftrivial-auto-var-init-max-size=*' is used without "
- "'-ftrivial-auto-var-init=zero' or '-ftrivial-auto-var-init=pattern'">;
-
-def err_drv_trivial_auto_var_init_max_size_invalid_value : Error<
- "'-ftrivial-auto-var-init-max-size=*' only accepts positive integers (in bytes)">;
-
def warn_drv_msp430_hwmult_unsupported : Warning<
"the given MCU does not support hardware multiply, but '-mhwmult' is set to "
"%0">, InGroup<InvalidCommandLineArgument>;
@@ -843,9 +655,7 @@ def err_drv_cannot_mix_options : Error<"cannot specify '%1' along with '%0'">;
def err_drv_invalid_object_mode : Error<
"OBJECT_MODE setting %0 is not recognized and is not a valid setting">;
-def err_drv_compile_mode_unsupported_aix : Error<
- "32-bit compile mode is not supported. Use OBJECT_MODE=64, -maix64 or -m64">;
-
+def err_aix_unsupported_tls_model : Error<"TLS model '%0' is not yet supported on AIX">;
def err_roptr_requires_data_sections: Error<"-mxcoff-roptr is supported only with -fdata-sections">;
def err_roptr_cannot_build_shared: Error<"-mxcoff-roptr is not supported with -shared">;
@@ -866,12 +676,6 @@ def err_cc1_round_trip_mismatch : Error<
def err_cc1_unbounded_vscale_min : Error<
"minimum vscale must be an unsigned integer greater than 0">;
-def err_conflicting_matrix_layout_flags: Error<
- "-fmatrix-memory-layout=%0 conflicts with -mllvm -matrix-default-layout=%1">;
-
-def err_drv_using_omit_rtti_component_without_no_rtti : Error<
- "-fexperimental-omit-vtable-rtti call only be used with -fno-rtti">;
-
def err_drv_ssp_missing_offset_argument : Error<
"'%0' is used without '-mstack-protector-guard-offset', and there is no default">;
@@ -900,54 +704,36 @@ def err_drv_target_variant_invalid : Error<
def err_drv_invalid_directx_shader_module : Error<
"invalid profile : %0">;
-def err_drv_dxc_invalid_matrix_layout : Error<
- "cannot specify /Zpr and /Zpc together">;
def err_drv_dxc_missing_target_profile : Error<
"target profile option (-T) is missing">;
-def err_drv_dxc_Fre_requires_Fo_metal
- : Error<"-Fre option requires -Fo option when targeting Metal">;
-def err_drv_dxc_invalid_shader_hash
- : Error<"cannot specify both /Zss and /Zsb">;
def err_drv_hlsl_unsupported_target : Error<
"HLSL code generation is unsupported for target '%0'">;
-def err_drv_hlsl_bad_shader_required_in_target : Error<
- "%select{shader model|Vulkan environment|shader stage}0 is required as %select{OS|environment}1 in target '%2' for HLSL code generation">;
-def err_drv_hlsl_16bit_types_unsupported: Error<
- "'%0' option requires target HLSL Version >= 2018%select{| and shader model >= 6.2}1, but HLSL Version is '%2'%select{| and shader model is '%3'}1">;
-def err_drv_hlsl_bad_shader_unsupported : Error<
- "%select{shader model|Vulkan environment|shader stage}0 '%1' in target '%2' is invalid for HLSL code generation">;
-def warn_drv_dxc_missing_dxv : Warning<
- "dxv not found; resulting DXIL will not be validated or signed for use in "
- "release environment">, InGroup<DXILValidation>;
-def warn_drv_dxc_missing_spirv_val : Warning<
- "spirv-val not found; resulting SPIR-V will not be validated">,
- InGroup<SPIRVValidation>;
+def warn_drv_dxc_missing_dxv : Warning<"dxv not found. "
+ "Resulting DXIL will not be validated or signed for use in release environments.">,
+ InGroup<DXILValidation>;
def err_drv_invalid_range_dxil_validator_version : Error<
- "invalid validator version : %0; validator version must be less than or "
- "equal to current internal version">;
+ "invalid validator version : %0\n"
+ "Validator version must be less than or equal to current internal version.">;
def err_drv_invalid_format_dxil_validator_version : Error<
- "invalid validator version : %0; format of validator version is "
- "\"<major>.<minor>\" (ex:\"1.4\")">;
+ "invalid validator version : %0\n"
+ "Format of validator version is \"<major>.<minor>\" (ex:\"1.4\").">;
def err_drv_invalid_empty_dxil_validator_version : Error<
- "invalid validator version : %0; if validator major version is 0, minor "
- "version must also be 0">;
+ "invalid validator version : %0\n"
+ "If validator major version is 0, minor version must also be 0.">;
def warn_drv_sarif_format_unstable : Warning<
"diagnostic formatting in SARIF mode is currently unstable">,
InGroup<DiagGroup<"sarif-format-unstable">>;
+def err_drv_riscv_unsupported_with_linker_relaxation : Error<
+ "%0 is unsupported with RISC-V linker relaxation (-mrelax)">;
+
def warn_drv_loongarch_conflicting_implied_val : Warning<
"ignoring '%0' as it conflicts with that implied by '%1' (%2)">,
InGroup<OptionIgnored>;
def err_drv_loongarch_invalid_mfpu_EQ : Error<
"invalid argument '%0' to -mfpu=; must be one of: 64, 32, none, 0 (alias for none)">;
-def err_drv_loongarch_wrong_fpu_width : Error<
- "wrong fpu width; %select{LSX|LASX}0 depends on 64-bit FPU">;
-def err_drv_loongarch_invalid_simd_option_combination : Error<
- "invalid option combination; LASX depends on LSX">;
-def err_drv_loongarch_invalid_msimd_EQ : Error<
- "invalid argument '%0' to -msimd=; must be one of: none, lsx, lasx">;
def err_drv_expand_response_file : Error<
"failed to expand response file: %0">;
@@ -957,45 +743,4 @@ def warn_drv_missing_multilib : Warning<
InGroup<DiagGroup<"missing-multilib">>;
def note_drv_available_multilibs : Note<
"available multilibs are:%0">;
-def err_drv_multilib_custom_error : Error<
- "multilib configuration error: %0">;
-def warn_drv_multilib_not_available_for_target: Warning<
- "no multilib structure encoded for Arm, Aarch64 and PPC targets">,
- InGroup<DiagGroup<"multilib-not-found">>;
-
-def err_drv_experimental_crel : Error<
- "-Wa,--allow-experimental-crel must be specified to use -Wa,--crel. "
- "CREL is experimental and uses a non-standard section type code">;
-
-def err_drv_experimental_sframe : Error<
- "-Wa,--allow-experimental-sframe must be specified to use -Wa,--gsframe. "
- "SFrames are experimental and may be removed at any time without warning">;
-
-def warn_android_unversioned_fallback : Warning<
- "using unversioned Android target directory %0 for target %1; unversioned "
- "directories will not be used in Clang 19 -- provide a versioned directory "
- "for the target version or lower instead">,
- InGroup<DiagGroup<"android-unversioned-fallback">>;
-
-def err_drv_triple_version_invalid : Error<
- "version '%0' in target triple '%1' is invalid">;
-
-def warn_missing_include_dirs : Warning<
- "no such include directory: '%0'">, InGroup<MissingIncludeDirs>, DefaultIgnore;
-
-def err_drv_malformed_warning_suppression_mapping : Error<
- "failed to process suppression mapping file '%0': %1">;
-
-def warn_drv_openacc_without_cir
- : Warning<"OpenACC directives will result in no runtime behavior; use "
- "-fclangir to enable runtime effect">,
- InGroup<SourceUsesOpenACC>;
-
-def warn_drv_gcc_install_dir_libstdcxx : Warning<
- "future releases of the clang compiler will prefer GCC installations "
- "containing libstdc++ include directories; '%0' would be chosen over '%1'">,
- InGroup<DiagGroup<"gcc-install-dir-libstdcxx">>;
-
-def err_drv_reflection_requires_cxx26 : Error<
- "option '%0' is only supported when compiling in C++26 mode">;
}
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 (const llvm::opt::Arg *a =
- args.getLastArg(clang::options::OPT_mrelocation_model)) {
+ args.getLastArg(clang::driver::options::OPT_mrelocation_model)) {
llvm::StringRef modelName = a->getValue();
auto relocModel =
llvm::StringSwitch<std::optional<llvm::Reloc::Model>>(modelName)
@@ -502,85 +214,24 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
}
// -pic-level and -pic-is-pie option.
- if (int picLevel =
- getLastArgIntValue(args, clang::options::OPT_pic_level, 0, diags)) {
+ if (int picLevel = getLastArgIntValue(
+ args, clang::driver::options::OPT_pic_level, 0, diags)) {
if (picLevel > 2)
diags.Report(clang::diag::err_drv_invalid_value)
- << args.getLastArg(clang::options::OPT_pic_level)->getAsString(args)
+ << args.getLastArg(clang::driver::options::OPT_pic_level)
+ ->getAsString(args)
<< picLevel;
opts.PICLevel = picLevel;
- if (args.hasArg(clang::options::OPT_pic_is_pie))
+ if (args.hasArg(clang::driver::options::OPT_pic_is_pie))
opts.IsPIE = 1;
}
- if (const llvm::opt::Arg *a =
- args.getLastArg(clang::options::OPT_fprofile_generate,
- clang::options::OPT_fprofile_generate_EQ)) {
- opts.setProfileInstr(llvm::driver::ProfileInstrKind::ProfileIRInstr);
- if (a->getOption().matches(clang::options::OPT_fprofile_generate_EQ)) {
- llvm::SmallString<128> path(a->getValue());
- llvm::sys::path::append(path, "default_%m.profraw");
- opts.InstrProfileOutput = std::string(path);
- }
- }
-
- if (auto A = args.getLastArg(clang::options::OPT_fprofile_use_EQ)) {
- opts.setProfileUse(llvm::driver::ProfileInstrKind::ProfileIRInstr);
- opts.ProfileInstrumentUsePath = A->getValue();
- }
-
- opts.SampleProfileFile =
- args.getLastArgValue(clang::options::OPT_fprofile_sample_use_EQ);
-
- if (args.hasFlag(clang::options::OPT_fpseudo_probe_for_profiling,
- clang::options::OPT_fno_pseudo_probe_for_profiling, false)) {
- opts.PseudoProbeForProfiling = 1;
- }
-
- // -mcmodel option.
- if (const llvm::opt::Arg *a =
- args.getLastArg(clang::options::OPT_mcmodel_EQ)) {
- llvm::StringRef modelName = a->getValue();
- std::optional<llvm::CodeModel::Model> codeModel = getCodeModel(modelName);
-
- if (codeModel.has_value())
- opts.CodeModel = modelName;
- else
- diags.Report(clang::diag::err_drv_invalid_value)
- << a->getAsString(args) << modelName;
- }
-
- if (const llvm::opt::Arg *arg =
- args.getLastArg(clang::options::OPT_mlarge_data_threshold_EQ)) {
- uint64_t LDT;
- if (llvm::StringRef(arg->getValue()).getAsInteger(/*Radix=*/10, LDT)) {
- diags.Report(clang::diag::err_drv_invalid_value)
- << arg->getSpelling() << arg->getValue();
- }
- opts.LargeDataThreshold = LDT;
- }
-
// This option is compatible with -f[no-]underscoring in gfortran.
- if (args.hasFlag(clang::options::OPT_fno_underscoring,
- clang::options::OPT_funderscoring, false)) {
+ if (args.hasFlag(clang::driver::options::OPT_fno_underscoring,
+ clang::driver::options::OPT_funderscoring, false)) {
opts.Underscoring = 0;
}
-
- if (const llvm::opt::Arg *arg =
- args.getLastArg(clang::options::OPT_complex_range_EQ)) {
- llvm::StringRef argValue = llvm::StringRef(arg->getValue());
- if (argValue == "full") {
- opts.setComplexRange(CodeGenOptions::ComplexRangeKind::CX_Full);
- } else if (argValue == "improved") {
- opts.setComplexRange(CodeGenOptions::ComplexRangeKind::CX_Improved);
- } else if (argValue == "basic") {
- opts.setComplexRange(CodeGenOptions::ComplexRangeKind::CX_Basic);
- } else {
- diags.Report(clang::diag::err_drv_invalid_value)
- << arg->getAsString(args) << arg->getValue();
- }
- }
}
/// Parses all target input arguments and populates the target
@@ -589,54 +240,19 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
/// \param [in] opts The target options instance to update
/// \param [in] args The list of input arguments (from the compiler invocation)
static void parseTargetArgs(TargetOptions &opts, llvm::opt::ArgList &args) {
- if (const llvm::opt::Arg *a = args.getLastArg(clang::options::OPT_triple))
+ if (const llvm::opt::Arg *a =
+ args.getLastArg(clang::driver::options::OPT_triple))
opts.triple = a->getValue();
- opts.atomicIgnoreDenormalMode =
- args.hasFlag(clang::options::OPT_fatomic_ignore_denormal_mode,
- clang::options::OPT_fno_atomic_ignore_denormal_mode, false);
- opts.atomicFineGrainedMemory =
- args.hasFlag(clang::options::OPT_fatomic_fine_grained_memory,
- clang::options::OPT_fno_atomic_fine_grained_memory, false);
- opts.atomicRemoteMemory =
- args.hasFlag(clang::options::OPT_fatomic_remote_memory,
- clang::options::OPT_fno_atomic_remote_memory, false);
-
- if (const llvm::opt::Arg *a = args.getLastArg(clang::options::OPT_target_cpu))
+ if (const llvm::opt::Arg *a =
+ args.getLastArg(clang::driver::options::OPT_target_cpu))
opts.cpu = a->getValue();
- if (const llvm::opt::Arg *a = args.getLastArg(clang::options::OPT_tune_cpu))
- opts.cpuToTuneFor = a->getValue();
-
for (const llvm::opt::Arg *currentArg :
- args.filtered(clang::options::OPT_target_feature))
+ args.filtered(clang::driver::options::OPT_target_feature))
opts.featuresAsWritten.emplace_back(currentArg->getValue());
-
- if (args.hasArg(clang::options::OPT_fdisable_real_10))
- opts.disabledRealKinds.push_back(10);
-
- if (args.hasArg(clang::options::OPT_fdisable_real_3))
- opts.disabledRealKinds.push_back(3);
-
- if (args.hasArg(clang::options::OPT_fdisable_integer_2))
- opts.disabledIntegerKinds.push_back(2);
-
- if (args.hasArg(clang::options::OPT_fdisable_integer_16))
- opts.disabledIntegerKinds.push_back(16);
-
- if (const llvm::opt::Arg *a = args.getLastArg(clang::options::OPT_mabi_EQ)) {
- llvm::StringRef V = a->getValue();
- // Normalize "vec-default" to an empty ABI name; the AIX extended Altivec
- // ABI is carried to the backend as the "vec-extabi" target-abi module flag.
- opts.abi = V == "vec-default" ? "" : V.str();
- }
-
- opts.SplitMachineFunctions =
- args.hasArg(clang::options::OPT_fsplit_machine_functions);
-
- opts.asmVerbose = args.hasFlag(clang::options::OPT_fverbose_asm,
- clang::options::OPT_fno_verbose_asm, false);
}
+
// Tweak the frontend configuration based on the frontend action
static void setUpFrontendBasedOnAction(FrontendOptions &opts) {
if (opts.programAction == DebugDumpParsingLog)
@@ -660,120 +276,113 @@ static std::optional<const char *> parseConvertArg(const char *s) {
static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
clang::DiagnosticsEngine &diags) {
+ unsigned numErrorsBefore = diags.getNumErrors();
+
// By default the frontend driver creates a ParseSyntaxOnly action.
opts.programAction = ParseSyntaxOnly;
// Treat multiple action options as an invocation error. Note that `clang
// -cc1` does accept multiple action options, but will only consider the
// rightmost one.
- if (args.hasMultipleArgs(clang::options::OPT_Action_Group)) {
- llvm::SmallString<32> buf;
- llvm::raw_svector_ostream os(buf);
- for (const llvm::opt::Arg *arg :
- args.filtered(clang::options::OPT_Action_Group)) {
- if (buf.size())
- os << ", ";
- os << "'" << arg->getSpelling() << "'";
- }
- diags.Report(clang::diag::err_drv_too_many_actions) << buf;
+ if (args.hasMultipleArgs(clang::driver::options::OPT_Action_Group)) {
+ const unsigned diagID = diags.getCustomDiagID(
+ clang::DiagnosticsEngine::Error, "Only one action option is allowed");
+ diags.Report(diagID);
return false;
}
// Identify the action (i.e. opts.ProgramAction)
if (const llvm::opt::Arg *a =
- args.getLastArg(clang::options::OPT_Action_Group)) {
+ args.getLastArg(clang::driver::options::OPT_Action_Group)) {
switch (a->getOption().getID()) {
default: {
llvm_unreachable("Invalid option in group!");
}
- case clang::options::OPT_test_io:
+ case clang::driver::options::OPT_test_io:
opts.programAction = InputOutputTest;
break;
- case clang::options::OPT_E:
+ case clang::driver::options::OPT_E:
opts.programAction = PrintPreprocessedInput;
break;
- case clang::options::OPT_fsyntax_only:
+ case clang::driver::options::OPT_fsyntax_only:
opts.programAction = ParseSyntaxOnly;
break;
- case clang::options::OPT_emit_fir:
+ case clang::driver::options::OPT_emit_fir:
opts.programAction = EmitFIR;
break;
- case clang::options::OPT_emit_hlfir:
+ case clang::driver::options::OPT_emit_hlfir:
opts.programAction = EmitHLFIR;
break;
- case clang::options::OPT_emit_llvm:
+ case clang::driver::options::OPT_emit_llvm:
opts.programAction = EmitLLVM;
break;
- case clang::options::OPT_emit_llvm_bc:
+ case clang::driver::options::OPT_emit_llvm_bc:
opts.programAction = EmitLLVMBitcode;
break;
- case clang::options::OPT_emit_obj:
+ case clang::driver::options::OPT_emit_obj:
opts.programAction = EmitObj;
break;
- case clang::options::OPT_S:
+ case clang::driver::options::OPT_S:
opts.programAction = EmitAssembly;
break;
- case clang::options::OPT_fdebug_unparse:
+ case clang::driver::options::OPT_fdebug_unparse:
opts.programAction = DebugUnparse;
break;
- case clang::options::OPT_fdebug_unparse_no_sema:
+ case clang::driver::options::OPT_fdebug_unparse_no_sema:
opts.programAction = DebugUnparseNoSema;
break;
- case clang::options::OPT_fdebug_unparse_with_symbols:
+ case clang::driver::options::OPT_fdebug_unparse_with_symbols:
opts.programAction = DebugUnparseWithSymbols;
break;
- case clang::options::OPT_fdebug_unparse_with_modules:
- opts.programAction = DebugUnparseWithModules;
- break;
- case clang::options::OPT_fdebug_dump_symbols:
+ case clang::driver::options::OPT_fdebug_dump_symbols:
opts.programAction = DebugDumpSymbols;
break;
- case clang::options::OPT_fdebug_dump_parse_tree:
+ case clang::driver::options::OPT_fdebug_dump_parse_tree:
opts.programAction = DebugDumpParseTree;
break;
- case clang::options::OPT_fdebug_dump_pft:
+ case clang::driver::options::OPT_fdebug_dump_pft:
opts.programAction = DebugDumpPFT;
break;
- case clang::options::OPT_fdebug_dump_all:
+ case clang::driver::options::OPT_fdebug_dump_all:
opts.programAction = DebugDumpAll;
break;
- case clang::options::OPT_fdebug_dump_parse_tree_no_sema:
+ case clang::driver::options::OPT_fdebug_dump_parse_tree_no_sema:
opts.programAction = DebugDumpParseTreeNoSema;
break;
- case clang::options::OPT_fdebug_dump_provenance:
+ case clang::driver::options::OPT_fdebug_dump_provenance:
opts.programAction = DebugDumpProvenance;
break;
- case clang::options::OPT_fdebug_dump_parsing_log:
+ case clang::driver::options::OPT_fdebug_dump_parsing_log:
opts.programAction = DebugDumpParsingLog;
break;
- case clang::options::OPT_fdebug_measure_parse_tree:
+ case clang::driver::options::OPT_fdebug_measure_parse_tree:
opts.programAction = DebugMeasureParseTree;
break;
- case clang::options::OPT_fdebug_pre_fir_tree:
+ case clang::driver::options::OPT_fdebug_pre_fir_tree:
opts.programAction = DebugPreFIRTree;
break;
- case clang::options::OPT_fget_symbols_sources:
+ case clang::driver::options::OPT_fget_symbols_sources:
opts.programAction = GetSymbolsSources;
break;
- case clang::options::OPT_fget_definition:
+ case clang::driver::options::OPT_fget_definition:
opts.programAction = GetDefinition;
break;
- case clang::options::OPT_init_only:
+ case clang::driver::options::OPT_init_only:
opts.programAction = InitOnly;
break;
// TODO:
- // case clang::options::OPT_emit_llvm:
- // case clang::options::OPT_emit_llvm_only:
- // case clang::options::OPT_emit_codegen_only:
- // case clang::options::OPT_emit_module:
+ // case clang::driver::options::OPT_emit_llvm:
+ // case clang::driver::options::OPT_emit_llvm_only:
+ // case clang::driver::options::OPT_emit_codegen_only:
+ // case clang::driver::options::OPT_emit_module:
// (...)
}
// Parse the values provided with `-fget-definition` (there should be 3
// integers)
if (llvm::opt::OptSpecifier(a->getOption().getID()) ==
- clang::options::OPT_fget_definition) {
+ clang::driver::options::OPT_fget_definition) {
unsigned optVals[3] = {0, 0, 0};
for (unsigned i = 0; i < 3; i++) {
@@ -793,28 +402,25 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
}
// Parsing -load <dsopath> option and storing shared object path
- if (llvm::opt::Arg *a = args.getLastArg(clang::options::OPT_load)) {
+ if (llvm::opt::Arg *a = args.getLastArg(clang::driver::options::OPT_load)) {
opts.plugins.push_back(a->getValue());
}
// Parsing -plugin <name> option and storing plugin name and setting action
- if (const llvm::opt::Arg *a = args.getLastArg(clang::options::OPT_plugin)) {
+ if (const llvm::opt::Arg *a =
+ args.getLastArg(clang::driver::options::OPT_plugin)) {
opts.programAction = PluginAction;
opts.actionName = a->getValue();
}
- opts.outputFile = args.getLastArgValue(clang::options::OPT_o);
- opts.dependencyOutputFile =
- args.getLastArgValue(clang::options::OPT_dependency_file);
- opts.dependencyTargets = args.getAllArgValues(clang::options::OPT_MT);
- opts.showHelp = args.hasArg(clang::options::OPT_help);
- opts.showVersion = args.hasArg(clang::options::OPT_version);
- opts.printSupportedCPUs =
- args.hasArg(clang::options::OPT_print_supported_cpus);
+ opts.outputFile = args.getLastArgValue(clang::driver::options::OPT_o);
+ opts.showHelp = args.hasArg(clang::driver::options::OPT_help);
+ opts.showVersion = args.hasArg(clang::driver::options::OPT_version);
// Get the input kind (from the value passed via `-x`)
InputKind dashX(Language::Unknown);
- if (const llvm::opt::Arg *a = args.getLastArg(clang::options::OPT_x)) {
+ if (const llvm::opt::Arg *a =
+ args.getLastArg(clang::driver::options::OPT_x)) {
llvm::StringRef xValue = a->getValue();
// Principal languages.
dashX = llvm::StringSwitch<InputKind>(xValue)
@@ -822,8 +428,6 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
// pre-processed inputs.
.Case("f95", Language::Fortran)
.Case("f95-cpp-input", Language::Fortran)
- // CUDA Fortran
- .Case("cuda", Language::Fortran)
.Default(Language::Unknown);
// Flang's intermediate representations.
@@ -841,7 +445,7 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
// Collect the input files and save them in our instance of FrontendOptions.
std::vector<std::string> inputs =
- args.getAllArgValues(clang::options::OPT_INPUT);
+ args.getAllArgValues(clang::driver::options::OPT_INPUT);
opts.inputs.clear();
if (inputs.empty())
// '-' is the default input if none is given.
@@ -861,47 +465,53 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
}
// Set fortranForm based on options -ffree-form and -ffixed-form.
- if (const auto *arg = args.getLastArg(clang::options::OPT_ffixed_form,
- clang::options::OPT_ffree_form)) {
- opts.fortranForm = arg->getOption().matches(clang::options::OPT_ffixed_form)
- ? FortranForm::FixedForm
- : FortranForm::FreeForm;
+ if (const auto *arg =
+ args.getLastArg(clang::driver::options::OPT_ffixed_form,
+ clang::driver::options::OPT_ffree_form)) {
+ opts.fortranForm =
+ arg->getOption().matches(clang::driver::options::OPT_ffixed_form)
+ ? FortranForm::FixedForm
+ : FortranForm::FreeForm;
}
// Set fixedFormColumns based on -ffixed-line-length=<value>
if (const auto *arg =
- args.getLastArg(clang::options::OPT_ffixed_line_length_EQ)) {
+ args.getLastArg(clang::driver::options::OPT_ffixed_line_length_EQ)) {
llvm::StringRef argValue = llvm::StringRef(arg->getValue());
+ bool correctness_of_input = !argValue.empty();
+ for(auto char_in_string: argValue) {
+ if(char_in_string>='0' && char_in_string<='9') {
+ continue;
+ } else {
+ correctness_of_input=false;
+ break;
+ }
+ }
std::int64_t columns = -1;
if (argValue == "none") {
columns = 0;
} else if (argValue.getAsInteger(/*Radix=*/10, columns)) {
- if (!argValue.empty() && llvm::all_of(argValue, llvm::isDigit)) {
- // Route oversized positive decimals to the large-columns diagnostic.
- columns = std::numeric_limits<std::int64_t>::max();
- } else {
- columns = -1;
- }
+ columns = -1;
}
- if (columns < 0) {
+ if(correctness_of_input && columns==-1) {
+ diags.Report(clang::diag::err_drv_large_columns)
+ << arg->getOption().getName() << arg->getValue();
+ } else if (columns < 0) {
diags.Report(clang::diag::err_drv_negative_columns)
<< arg->getOption().getName() << arg->getValue();
} else if (columns == 0) {
- opts.fixedFormColumns = std::nullopt;
+ opts.fixedFormColumns = 1000000;
} else if (columns < 7) {
diags.Report(clang::diag::err_drv_small_columns)
<< arg->getOption().getName() << arg->getValue() << "7";
- } else if (columns > std::numeric_limits<int>::max()) {
- diags.Report(clang::diag::err_drv_large_columns)
- << arg->getOption().getName() << arg->getValue()
- << std::numeric_limits<int>::max();
} else {
opts.fixedFormColumns = columns;
}
}
// Set conversion based on -fconvert=<value>
- if (const auto *arg = args.getLastArg(clang::options::OPT_fconvert_EQ)) {
+ if (const auto *arg =
+ args.getLastArg(clang::driver::options::OPT_fconvert_EQ)) {
const char *argValue = arg->getValue();
if (auto convert = parseConvertArg(argValue))
opts.envDefaults.push_back({"FORT_CONVERT", *convert});
@@ -911,96 +521,41 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
}
// -f{no-}implicit-none
- opts.features.Enable(Fortran::common::LanguageFeature::ImplicitNoneTypeAlways,
- args.hasFlag(clang::options::OPT_fimplicit_none,
- clang::options::OPT_fno_implicit_none,
- false));
-
- // -f{no-}implicit-none-ext
- opts.features.Enable(Fortran::common::LanguageFeature::ImplicitNoneExternal,
- args.hasFlag(clang::options::OPT_fimplicit_none_ext,
- clang::options::OPT_fno_implicit_none_ext,
- false));
-
- // -f{no-}implicit-module-prefix
opts.features.Enable(
- Fortran::common::LanguageFeature::ImplicitModulePrefix,
- args.hasFlag(clang::options::OPT_fimplicit_module_prefix,
- clang::options::OPT_fno_implicit_module_prefix, false));
+ Fortran::common::LanguageFeature::ImplicitNoneTypeAlways,
+ args.hasFlag(clang::driver::options::OPT_fimplicit_none,
+ clang::driver::options::OPT_fno_implicit_none, false));
// -f{no-}backslash
opts.features.Enable(Fortran::common::LanguageFeature::BackslashEscapes,
- args.hasFlag(clang::options::OPT_fbackslash,
- clang::options::OPT_fno_backslash, false));
+ args.hasFlag(clang::driver::options::OPT_fbackslash,
+ clang::driver::options::OPT_fno_backslash,
+ false));
// -f{no-}logical-abbreviations
opts.features.Enable(
Fortran::common::LanguageFeature::LogicalAbbreviations,
- args.hasFlag(clang::options::OPT_flogical_abbreviations,
- clang::options::OPT_fno_logical_abbreviations, false));
-
- // -f{no-}unsigned
- opts.features.Enable(Fortran::common::LanguageFeature::Unsigned,
- args.hasFlag(clang::options::OPT_funsigned,
- clang::options::OPT_fno_unsigned, false));
-
- // -f{no-}out-of-bounds-subscripts
- opts.features.Enable(
- Fortran::common::LanguageFeature::OutOfBoundsSubscripts,
- args.hasFlag(clang::options::OPT_fout_of_bounds_subscripts,
- clang::options::OPT_fno_out_of_bounds_subscripts, true));
-
- // -frelaxed-c-loc-checks
- if (args.hasArg(clang::options::OPT_relaxed_c_loc)) {
- opts.features.Enable(Fortran::common::LanguageFeature::RelaxedCLocChecks);
- }
-
- // -f{no-}openacc-default-none-scalars-strict
- opts.features.Enable(
- Fortran::common::LanguageFeature::OpenAccDefaultNoneScalarsStrict,
- args.hasFlag(clang::options::OPT_fopenacc_default_none_scalars_strict,
- clang::options::OPT_fno_openacc_default_none_scalars_strict,
+ args.hasFlag(clang::driver::options::OPT_flogical_abbreviations,
+ clang::driver::options::OPT_fno_logical_abbreviations,
false));
- // -f{no-}openacc-multiple-names-in-routine
- opts.features.Enable(
- Fortran::common::LanguageFeature::OpenACCMultipleNamesInRoutine,
- args.hasFlag(clang::options::OPT_fopenacc_multiple_names_in_routine,
- clang::options::OPT_fno_openacc_multiple_names_in_routine,
- true));
-
- // -f{no-}prefer-intrinsic-module-use-association
- if (const auto *arg = args.getLastArg(
- clang::options::OPT_fprefer_intrinsic_module_use_association,
- clang::options::OPT_fno_prefer_intrinsic_module_use_association)) {
- opts.features.Enable(
- Fortran::common::LanguageFeature::PreferIntrinsicModuleUseAssociation,
- arg->getOption().matches(
- clang::options::OPT_fprefer_intrinsic_module_use_association));
- }
-
// -f{no-}xor-operator
- opts.features.Enable(Fortran::common::LanguageFeature::XOROperator,
- args.hasFlag(clang::options::OPT_fxor_operator,
- clang::options::OPT_fno_xor_operator,
- false));
+ opts.features.Enable(
+ Fortran::common::LanguageFeature::XOROperator,
+ args.hasFlag(clang::driver::options::OPT_fxor_operator,
+ clang::driver::options::OPT_fno_xor_operator, false));
// -fno-automatic
- if (args.hasArg(clang::options::OPT_fno_automatic)) {
+ if (args.hasArg(clang::driver::options::OPT_fno_automatic)) {
opts.features.Enable(Fortran::common::LanguageFeature::DefaultSave);
}
- // -f{no}-save-main-program
- opts.features.Enable(Fortran::common::LanguageFeature::SaveMainProgram,
- args.hasFlag(clang::options::OPT_fsave_main_program,
- clang::options::OPT_fno_save_main_program,
- false));
-
- if (args.hasArg(clang::options::OPT_falternative_parameter_statement)) {
+ if (args.hasArg(
+ clang::driver::options::OPT_falternative_parameter_statement)) {
opts.features.Enable(Fortran::common::LanguageFeature::OldStyleParameter);
}
if (const llvm::opt::Arg *arg =
- args.getLastArg(clang::options::OPT_finput_charset_EQ)) {
+ args.getLastArg(clang::driver::options::OPT_finput_charset_EQ)) {
llvm::StringRef argValue = arg->getValue();
if (argValue == "utf-8") {
opts.encoding = Fortran::parser::Encoding::UTF_8;
@@ -1015,19 +570,28 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
setUpFrontendBasedOnAction(opts);
opts.dashX = dashX;
- return !diags.hasUncompilableErrorOccurred();
+ return diags.getNumErrors() == numErrorsBefore;
}
// Generate the path to look for intrinsic modules
-static std::string getIntrinsicDir(const char *argv) {
+static std::string getIntrinsicDir() {
// TODO: Find a system independent API
llvm::SmallString<128> driverPath;
- driverPath.assign(llvm::sys::fs::getMainExecutable(argv, nullptr));
+ driverPath.assign(llvm::sys::fs::getMainExecutable(nullptr, nullptr));
llvm::sys::path::remove_filename(driverPath);
driverPath.append("/../include/flang/");
return std::string(driverPath);
}
+// Generate the path to look for OpenMP headers
+static std::string getOpenMPHeadersDir() {
+ llvm::SmallString<128> includePath;
+ includePath.assign(llvm::sys::fs::getMainExecutable(nullptr, nullptr));
+ llvm::sys::path::remove_filename(includePath);
+ includePath.append("/../include/flang/OpenMP/");
+ return std::string(includePath);
+}
+
/// Parses all preprocessor input arguments and populates the preprocessor
/// options accordingly.
///
@@ -1036,9 +600,9 @@ static std::string getIntrinsicDir(const char *argv) {
static void parsePreprocessorArgs(Fortran::frontend::PreprocessorOptions &opts,
llvm::opt::ArgList &args) {
// Add macros from the command line.
- for (const auto *currentArg :
- args.filtered(clang::options::OPT_D, clang::options::OPT_U)) {
- if (currentArg->getOption().matches(clang::options::OPT_D)) {
+ for (const auto *currentArg : args.filtered(clang::driver::options::OPT_D,
+ clang::driver::options::OPT_U)) {
+ if (currentArg->getOption().matches(clang::driver::options::OPT_D)) {
opts.addMacroDef(currentArg->getValue());
} else {
opts.addMacroUndef(currentArg->getValue());
@@ -1046,212 +610,116 @@ static void parsePreprocessorArgs(Fortran::frontend::PreprocessorOptions &opts,
}
// Add the ordered list of -I's.
- for (const auto *currentArg : args.filtered(clang::options::OPT_I))
+ for (const auto *currentArg : args.filtered(clang::driver::options::OPT_I))
opts.searchDirectoriesFromDashI.emplace_back(currentArg->getValue());
// Prepend the ordered list of -intrinsic-modules-path
// to the default location to search.
for (const auto *currentArg :
- args.filtered(clang::options::OPT_fintrinsic_modules_path))
+ args.filtered(clang::driver::options::OPT_fintrinsic_modules_path))
opts.searchDirectoriesFromIntrModPath.emplace_back(currentArg->getValue());
// -cpp/-nocpp
- if (const auto *currentArg =
- args.getLastArg(clang::options::OPT_cpp, clang::options::OPT_nocpp))
- opts.macrosFlag = (currentArg->getOption().matches(clang::options::OPT_cpp))
- ? PPMacrosFlag::Include
- : PPMacrosFlag::Exclude;
- // Enable -cpp based on -x unless explicitly disabled with -nocpp
- if (opts.macrosFlag != PPMacrosFlag::Exclude)
- if (const auto *dashX = args.getLastArg(clang::options::OPT_x))
- opts.macrosFlag = llvm::StringSwitch<PPMacrosFlag>(dashX->getValue())
- .Case("f95-cpp-input", PPMacrosFlag::Include)
- .Default(opts.macrosFlag);
-
- opts.noReformat = args.hasArg(clang::options::OPT_fno_reformat);
- opts.preprocessIncludeLines =
- args.hasArg(clang::options::OPT_fpreprocess_include_lines);
- opts.noLineDirectives = args.hasArg(clang::options::OPT_P);
- opts.showMacros = args.hasArg(clang::options::OPT_dM);
+ if (const auto *currentArg = args.getLastArg(
+ clang::driver::options::OPT_cpp, clang::driver::options::OPT_nocpp))
+ opts.macrosFlag =
+ (currentArg->getOption().matches(clang::driver::options::OPT_cpp))
+ ? PPMacrosFlag::Include
+ : PPMacrosFlag::Exclude;
+
+ opts.noReformat = args.hasArg(clang::driver::options::OPT_fno_reformat);
+ opts.noLineDirectives = args.hasArg(clang::driver::options::OPT_P);
}
/// Parses all semantic related arguments and populates the variables
/// options accordingly. Returns false if new errors are generated.
static bool parseSemaArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
clang::DiagnosticsEngine &diags) {
+ unsigned numErrorsBefore = diags.getNumErrors();
+
// -J/module-dir option
- std::vector<std::string> moduleDirList =
- args.getAllArgValues(clang::options::OPT_module_dir);
- // User can only specify one -J/-module-dir directory, but may repeat
- // -J/-module-dir as long as the directory is the same each time.
+ auto moduleDirList =
+ args.getAllArgValues(clang::driver::options::OPT_module_dir);
+ // User can only specify -J/-module-dir once
// https://gcc.gnu.org/onlinedocs/gfortran/Directory-Options.html
- std::sort(moduleDirList.begin(), moduleDirList.end());
- moduleDirList.erase(std::unique(moduleDirList.begin(), moduleDirList.end()),
- moduleDirList.end());
if (moduleDirList.size() > 1) {
const unsigned diagID =
diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
- "Only one '-module-dir/-J' directory allowed. "
- "'-module-dir/-J' may be given multiple times "
- "but the directory must be the same each time.");
+ "Only one '-module-dir/-J' option allowed");
diags.Report(diagID);
}
if (moduleDirList.size() == 1)
res.setModuleDir(moduleDirList[0]);
// -fdebug-module-writer option
- if (args.hasArg(clang::options::OPT_fdebug_module_writer)) {
+ if (args.hasArg(clang::driver::options::OPT_fdebug_module_writer)) {
res.setDebugModuleDir(true);
}
- // -fhermetic-module-files option
- if (args.hasArg(clang::options::OPT_fhermetic_module_files)) {
- res.setHermeticModuleFileOutput(true);
- }
-
// -module-suffix
if (const auto *moduleSuffix =
- args.getLastArg(clang::options::OPT_module_suffix)) {
+ args.getLastArg(clang::driver::options::OPT_module_suffix)) {
res.setModuleFileSuffix(moduleSuffix->getValue());
}
// -f{no-}analyzed-objects-for-unparse
- res.setUseAnalyzedObjectsForUnparse(
- args.hasFlag(clang::options::OPT_fanalyzed_objects_for_unparse,
- clang::options::OPT_fno_analyzed_objects_for_unparse, true));
+ res.setUseAnalyzedObjectsForUnparse(args.hasFlag(
+ clang::driver::options::OPT_fanalyzed_objects_for_unparse,
+ clang::driver::options::OPT_fno_analyzed_objects_for_unparse, true));
- return !diags.hasUncompilableErrorOccurred();
+ return diags.getNumErrors() == numErrorsBefore;
}
/// Parses all diagnostics related arguments and populates the variables
/// options accordingly. Returns false if new errors are generated.
-/// FC1 driver entry point for parsing diagnostic arguments.
static bool parseDiagArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
clang::DiagnosticsEngine &diags) {
- auto &features{res.getFrontendOpts().features};
- // The order of these flags (-pedantic -W<feature> -w) is important and is
- // chosen to match clang's behavior.
-
- // -pedantic
- if (args.hasArg(clang::options::OPT_pedantic)) {
- features.WarnOnAllNonstandard();
- features.WarnOnAllUsage();
- res.setEnableConformanceChecks();
- res.setEnableUsageChecks();
- }
+ unsigned numErrorsBefore = diags.getNumErrors();
// -Werror option
// TODO: Currently throws a Diagnostic for anything other than -W<error>,
// this has to change when other -W<opt>'s are supported.
- if (args.hasArg(clang::options::OPT_W_Joined)) {
- const auto &wArgs = args.getAllArgValues(clang::options::OPT_W_Joined);
- // TODO: Consider using std::string_view instead of llvm::StringRef
- // when moving to C++20:
- for (const llvm::StringRef wArg : wArgs) {
+ if (args.hasArg(clang::driver::options::OPT_W_Joined)) {
+ const auto &wArgs =
+ args.getAllArgValues(clang::driver::options::OPT_W_Joined);
+ for (const auto &wArg : wArgs) {
if (wArg == "error") {
res.setWarnAsErr(true);
- // -Wfatal-errors
- } else if (wArg == "fatal-errors") {
- res.setMaxErrors(1);
- // -W[no-]<feature>
- } else if (features.EnableWarning(wArg)) {
- if (auto canonical{features.CheckDeprecatedSpelling(wArg)}) {
- std::string suggestion{*canonical};
- if (wArg.starts_with("no-")) {
- suggestion = "no-" + suggestion;
- }
- const unsigned diagID =
- diags.getCustomDiagID(clang::DiagnosticsEngine::Warning,
- "-W%0 is deprecated; use -W%1 instead");
- diags.Report(diagID) << wArg << suggestion;
- }
} else {
- const unsigned diagID = diags.getCustomDiagID(
- clang::DiagnosticsEngine::Error, "Unknown diagnostic option: -W%0");
- diags.Report(diagID) << wArg;
+ const unsigned diagID =
+ diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
+ "Only `-Werror` is supported currently.");
+ diags.Report(diagID);
}
}
}
- // -w
- if (args.hasArg(clang::options::OPT_w)) {
- features.DisableAllWarnings();
- res.setDisableWarnings();
- }
+ // Default to off for `flang-new -fc1`.
+ res.getFrontendOpts().showColors =
+ parseShowColorsArgs(args, /*defaultDiagColor=*/false);
- // Default to off for `flang -fc1`.
- bool showColors{parseShowColorsArgs(args, false)};
- auto colorsMode =
- showColors ? clang::ShowColorsKind::On : clang::ShowColorsKind::Off;
- diags.getDiagnosticOptions().setShowColors(colorsMode);
- res.getDiagnosticOpts().setShowColors(colorsMode);
- res.getFrontendOpts().showColors = showColors;
- return !diags.hasUncompilableErrorOccurred();
+ return diags.getNumErrors() == numErrorsBefore;
}
/// Parses all Dialect related arguments and populates the variables
/// options accordingly. Returns false if new errors are generated.
static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
clang::DiagnosticsEngine &diags) {
- // -fd-lines-as-code
- if (args.hasArg(clang::options::OPT_fd_lines_as_code)) {
- if (res.getFrontendOpts().fortranForm == FortranForm::FreeForm) {
- const unsigned fdLinesAsWarning = diags.getCustomDiagID(
- clang::DiagnosticsEngine::Warning,
- "‘-fd-lines-as-code’ has no effect in free form.");
- diags.Report(fdLinesAsWarning);
- } else {
- res.getFrontendOpts().features.Enable(
- Fortran::common::LanguageFeature::OldDebugLines, true);
- }
- }
-
- // -fd-lines-as-comments
- if (args.hasArg(clang::options::OPT_fd_lines_as_comments)) {
- if (res.getFrontendOpts().fortranForm == FortranForm::FreeForm) {
- const unsigned fdLinesAsWarning = diags.getCustomDiagID(
- clang::DiagnosticsEngine::Warning,
- "‘-fd-lines-as-comments’ has no effect in free form.");
- diags.Report(fdLinesAsWarning);
- } else {
- res.getFrontendOpts().features.Enable(
- Fortran::common::LanguageFeature::OldDebugLines, false);
- }
- }
+ unsigned numErrorsBefore = diags.getNumErrors();
// -fdefault* family
- if (const llvm::opt::Arg *arg =
- args.getLastArg(clang::options::OPT_fdefault_real_8,
- clang::options::OPT_fdefault_real_4)) {
- const llvm::opt::Option &opt = arg->getOption();
- if (opt.matches(clang::options::OPT_fdefault_real_8)) {
- res.getDefaultKinds().set_defaultRealKind(8);
- res.getDefaultKinds().set_doublePrecisionKind(16);
- } else if (opt.matches(clang::options::OPT_fdefault_real_4)) {
- res.getDefaultKinds().set_defaultRealKind(4);
- res.getDefaultKinds().set_doublePrecisionKind(8);
- }
+ if (args.hasArg(clang::driver::options::OPT_fdefault_real_8)) {
+ res.getDefaultKinds().set_defaultRealKind(8);
+ res.getDefaultKinds().set_doublePrecisionKind(16);
}
- if (const llvm::opt::Arg *arg =
- args.getLastArg(clang::options::OPT_fdefault_integer_8,
- clang::options::OPT_fdefault_integer_4)) {
- const llvm::opt::Option &opt = arg->getOption();
- if (opt.matches(clang::options::OPT_fdefault_integer_8)) {
- res.getDefaultKinds().set_defaultIntegerKind(8);
- res.getDefaultKinds().set_subscriptIntegerKind(8);
- res.getDefaultKinds().set_sizeIntegerKind(8);
- res.getDefaultKinds().set_defaultLogicalKind(8);
- } else if (opt.matches(clang::options::OPT_fdefault_integer_4)) {
- // Note that the subscript integer kind is set to 8 here. If a
- // default-integer-kind is not provided, it is also set to 8.
- res.getDefaultKinds().set_defaultIntegerKind(4);
- res.getDefaultKinds().set_subscriptIntegerKind(8);
- res.getDefaultKinds().set_sizeIntegerKind(4);
- res.getDefaultKinds().set_defaultLogicalKind(4);
- }
+ if (args.hasArg(clang::driver::options::OPT_fdefault_integer_8)) {
+ res.getDefaultKinds().set_defaultIntegerKind(8);
+ res.getDefaultKinds().set_subscriptIntegerKind(8);
+ res.getDefaultKinds().set_sizeIntegerKind(8);
+ res.getDefaultKinds().set_defaultLogicalKind(8);
}
- if (args.hasArg(clang::options::OPT_fdefault_double_8)) {
- if (!args.hasArg(clang::options::OPT_fdefault_real_8)) {
+ if (args.hasArg(clang::driver::options::OPT_fdefault_double_8)) {
+ if (!args.hasArg(clang::driver::options::OPT_fdefault_real_8)) {
// -fdefault-double-8 has to be used with -fdefault-real-8
// to be compatible with gfortran
const unsigned diagID = diags.getCustomDiagID(
@@ -1262,31 +730,102 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
// https://gcc.gnu.org/onlinedocs/gfortran/Fortran-Dialect-Options.html
res.getDefaultKinds().set_doublePrecisionKind(8);
}
- if (args.hasArg(clang::options::OPT_flarge_sizes))
+ if (args.hasArg(clang::driver::options::OPT_flarge_sizes))
res.getDefaultKinds().set_sizeIntegerKind(8);
- // -x cuda
- auto language = args.getLastArgValue(clang::options::OPT_x);
- if (language == "cuda") {
+ // -fopenmp and -fopenacc
+ if (args.hasArg(clang::driver::options::OPT_fopenacc)) {
res.getFrontendOpts().features.Enable(
- Fortran::common::LanguageFeature::CUDA);
+ Fortran::common::LanguageFeature::OpenACC);
}
-
- // -fopenacc
- if (args.hasArg(clang::options::OPT_fopenacc)) {
+ if (args.hasArg(clang::driver::options::OPT_fopenmp)) {
+ // By default OpenMP is set to 1.1 version
+ res.getLangOpts().OpenMPVersion = 11;
res.getFrontendOpts().features.Enable(
- Fortran::common::LanguageFeature::OpenACC);
+ Fortran::common::LanguageFeature::OpenMP);
+ if (int Version = getLastArgIntValue(
+ args, clang::driver::options::OPT_fopenmp_version_EQ,
+ res.getLangOpts().OpenMPVersion, diags)) {
+ res.getLangOpts().OpenMPVersion = Version;
+ }
+ if (args.hasArg(clang::driver::options::OPT_fopenmp_is_target_device)) {
+ res.getLangOpts().OpenMPIsTargetDevice = 1;
+
+ // Get OpenMP host file path if any and report if a non existent file is
+ // found
+ if (auto *arg = args.getLastArg(
+ clang::driver::options::OPT_fopenmp_host_ir_file_path)) {
+ res.getLangOpts().OMPHostIRFile = arg->getValue();
+ if (!llvm::sys::fs::exists(res.getLangOpts().OMPHostIRFile))
+ diags.Report(clang::diag::err_drv_omp_host_ir_file_not_found)
+ << res.getLangOpts().OMPHostIRFile;
+ }
+
+ if (args.hasFlag(
+ clang::driver::options::OPT_fopenmp_assume_teams_oversubscription,
+ clang::driver::options::
+ OPT_fno_openmp_assume_teams_oversubscription,
+ /*Default=*/false))
+ res.getLangOpts().OpenMPTeamSubscription = true;
+
+ if (args.hasArg(
+ clang::driver::options::OPT_fopenmp_assume_no_thread_state))
+ res.getLangOpts().OpenMPNoThreadState = 1;
+
+ if (args.hasArg(
+ clang::driver::options::OPT_fopenmp_assume_no_nested_parallelism))
+ res.getLangOpts().OpenMPNoNestedParallelism = 1;
+
+ if (args.hasFlag(clang::driver::options::
+ OPT_fopenmp_assume_threads_oversubscription,
+ clang::driver::options::
+ OPT_fno_openmp_assume_threads_oversubscription,
+ /*Default=*/false))
+ res.getLangOpts().OpenMPThreadSubscription = true;
+
+ if ((args.hasArg(clang::driver::options::OPT_fopenmp_target_debug) ||
+ args.hasArg(clang::driver::options::OPT_fopenmp_target_debug_EQ))) {
+ res.getLangOpts().OpenMPTargetDebug = getLastArgIntValue(
+ args, clang::driver::options::OPT_fopenmp_target_debug_EQ,
+ res.getLangOpts().OpenMPTargetDebug, diags);
+
+ if (!res.getLangOpts().OpenMPTargetDebug &&
+ args.hasArg(clang::driver::options::OPT_fopenmp_target_debug))
+ res.getLangOpts().OpenMPTargetDebug = 1;
+ }
+ }
+
+ switch (llvm::Triple(res.getTargetOpts().triple).getArch()) {
+ case llvm::Triple::nvptx:
+ case llvm::Triple::nvptx64:
+ case llvm::Triple::amdgcn:
+ if (!res.getLangOpts().OpenMPIsTargetDevice) {
+ const unsigned diagID = diags.getCustomDiagID(
+ clang::DiagnosticsEngine::Error,
+ "OpenMP AMDGPU/NVPTX is only prepared to deal with device code.");
+ diags.Report(diagID);
+ }
+ res.getLangOpts().OpenMPIsGPU = 1;
+ break;
+ default:
+ res.getLangOpts().OpenMPIsGPU = 0;
+ break;
+ }
}
+ // -pedantic
+ if (args.hasArg(clang::driver::options::OPT_pedantic)) {
+ res.setEnableConformanceChecks();
+ res.setEnableUsageChecks();
+ }
// -std=f2018
// TODO: Set proper options when more fortran standards
// are supported.
- if (args.hasArg(clang::options::OPT_std_EQ)) {
- auto standard = args.getLastArgValue(clang::options::OPT_std_EQ);
+ if (args.hasArg(clang::driver::options::OPT_std_EQ)) {
+ auto standard = args.getLastArgValue(clang::driver::options::OPT_std_EQ);
// We only allow f2018 as the given standard
- if (standard == "f2018") {
+ if (standard.equals("f2018")) {
res.setEnableConformanceChecks();
- res.getFrontendOpts().features.WarnOnAllNonstandard();
} else {
const unsigned diagID =
diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
@@ -1294,241 +833,7 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
diags.Report(diagID);
}
}
- // -fcoarray
- if (args.hasArg(clang::options::OPT_fcoarray)) {
- res.getFrontendOpts().features.Enable(
- Fortran::common::LanguageFeature::Coarray);
- const unsigned diagID =
- diags.getCustomDiagID(clang::DiagnosticsEngine::Warning,
- "Support for multi image Fortran features is "
- "still experimental and in development.");
- diags.Report(diagID);
- }
-
- return !diags.hasUncompilableErrorOccurred();
-}
-
-/// Parses all OpenMP related arguments if the -fopenmp option is present,
-/// populating the \c res object accordingly. Returns false if new errors are
-/// generated.
-static bool parseOpenMPArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
- clang::DiagnosticsEngine &diags) {
- llvm::opt::Arg *arg = args.getLastArg(clang::options::OPT_fopenmp,
- clang::options::OPT_fno_openmp);
- if (!arg || arg->getOption().matches(clang::options::OPT_fno_openmp)) {
- bool isSimdSpecified =
- args.hasFlag(clang::options::OPT_fopenmp_simd,
- clang::options::OPT_fno_openmp_simd, /*Default=*/false);
- if (!isSimdSpecified)
- return true;
- res.getLangOpts().OpenMPSimd = 1;
- }
-
- llvm::Triple t(res.getTargetOpts().triple);
-
- constexpr unsigned newestFullySupported = 31;
- constexpr unsigned latestFinalized = 60;
- // By default OpenMP is set to the most recent fully supported version
- res.getLangOpts().OpenMPVersion = newestFullySupported;
- res.getFrontendOpts().features.Enable(
- Fortran::common::LanguageFeature::OpenMP);
- if (auto *arg = args.getLastArg(clang::options::OPT_fopenmp_version_EQ)) {
- llvm::SmallVector<unsigned> ompVersions;
- for (llvm::omp::Version v : llvm::omp::getOpenMPVersions()) {
- ompVersions.push_back(static_cast<unsigned>(v));
- }
- unsigned oldVersions[] = {11, 20, 25, 30};
- unsigned version = 0;
-
- auto reportBadVersion = [&](llvm::StringRef value) {
- const unsigned diagID =
- diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
- "'%0' is not a valid OpenMP version in '%1', "
- "valid versions are %2");
- std::string buffer;
- llvm::raw_string_ostream versions(buffer);
- llvm::interleaveComma(ompVersions, versions);
-
- diags.Report(diagID) << value << arg->getAsString(args) << versions.str();
- };
-
- llvm::StringRef value = arg->getValue();
- if (!value.getAsInteger(/*radix=*/10, version)) {
- if (llvm::is_contained(ompVersions, version)) {
- res.getLangOpts().OpenMPVersion = version;
-
- if (version > latestFinalized)
- diags.Report(clang::diag::warn_openmp_spec_incomplete) << version;
- else if (version > newestFullySupported)
- diags.Report(clang::diag::warn_openmp_impl_incomplete) << version;
- } else if (llvm::is_contained(oldVersions, version)) {
- const unsigned diagID =
- diags.getCustomDiagID(clang::DiagnosticsEngine::Warning,
- "OpenMP version %0 is no longer supported, "
- "assuming version %1");
- std::string assumed = std::to_string(res.getLangOpts().OpenMPVersion);
- diags.Report(diagID) << value << assumed;
- } else {
- reportBadVersion(value);
- }
- } else {
- reportBadVersion(value);
- }
- }
-
- if (args.hasFlag(clang::options::OPT_fopenmp_assume_teams_oversubscription,
- clang::options::OPT_fno_openmp_assume_teams_oversubscription,
- /*Default=*/false))
- res.getLangOpts().OpenMPTeamSubscription = true;
- if (args.hasFlag(
- clang::options::OPT_fopenmp_assume_threads_oversubscription,
- clang::options::OPT_fno_openmp_assume_threads_oversubscription,
- /*Default=*/false))
- res.getLangOpts().OpenMPThreadSubscription = true;
-
- if (args.hasArg(clang::options::OPT_fopenmp_force_usm)) {
- res.getLangOpts().OpenMPForceUSM = 1;
- }
- if (args.hasArg(clang::options::OPT_fopenmp_is_target_device)) {
- res.getLangOpts().OpenMPIsTargetDevice = 1;
-
- // Get OpenMP host file path if any and report if a non existent file is
- // found
- if (auto *arg =
- args.getLastArg(clang::options::OPT_fopenmp_host_ir_file_path)) {
- res.getLangOpts().OMPHostIRFile = arg->getValue();
- if (!llvm::sys::fs::exists(res.getLangOpts().OMPHostIRFile))
- diags.Report(clang::diag::err_omp_host_ir_file_not_found)
- << res.getLangOpts().OMPHostIRFile;
- }
-
- if (args.hasArg(clang::options::OPT_fopenmp_assume_no_thread_state))
- res.getLangOpts().OpenMPNoThreadState = 1;
-
- if (args.hasArg(clang::options::OPT_fopenmp_assume_no_nested_parallelism))
- res.getLangOpts().OpenMPNoNestedParallelism = 1;
-
- if ((args.hasArg(clang::options::OPT_fopenmp_target_debug) ||
- args.hasArg(clang::options::OPT_fopenmp_target_debug_EQ))) {
- res.getLangOpts().OpenMPTargetDebug =
- getLastArgIntValue(args, clang::options::OPT_fopenmp_target_debug_EQ,
- res.getLangOpts().OpenMPTargetDebug, diags);
-
- if (!res.getLangOpts().OpenMPTargetDebug &&
- args.hasArg(clang::options::OPT_fopenmp_target_debug))
- res.getLangOpts().OpenMPTargetDebug = 1;
- }
- if (args.hasArg(clang::options::OPT_no_offloadlib))
- res.getLangOpts().NoGPULib = 1;
- }
- if (llvm::Triple(res.getTargetOpts().triple).isGPU()) {
- if (!res.getLangOpts().OpenMPIsTargetDevice) {
- const unsigned diagID = diags.getCustomDiagID(
- clang::DiagnosticsEngine::Error,
- "OpenMP GPU is only prepared to deal with device code.");
- diags.Report(diagID);
- }
- res.getLangOpts().OpenMPIsGPU = 1;
- } else {
- res.getLangOpts().OpenMPIsGPU = 0;
- }
-
- // Get the OpenMP target triples if any.
- if (auto *arg = args.getLastArg(clang::options::OPT_offload_targets_EQ)) {
- enum ArchPtrSize { Arch16Bit, Arch32Bit, Arch64Bit };
- auto getArchPtrSize = [](const llvm::Triple &triple) {
- if (triple.isArch16Bit())
- return Arch16Bit;
- if (triple.isArch32Bit())
- return Arch32Bit;
- assert(triple.isArch64Bit() && "Expected 64-bit architecture");
- return Arch64Bit;
- };
-
- for (unsigned i = 0; i < arg->getNumValues(); ++i) {
- llvm::Triple tt(arg->getValue(i));
-
- if (tt.getArch() == llvm::Triple::UnknownArch ||
- !(tt.getArch() == llvm::Triple::aarch64 || tt.isPPC() ||
- tt.getArch() == llvm::Triple::systemz ||
- tt.getArch() == llvm::Triple::x86 ||
- tt.getArch() == llvm::Triple::x86_64 || tt.isGPU()))
- diags.Report(clang::diag::err_drv_invalid_omp_target)
- << arg->getValue(i);
- else if (getArchPtrSize(t) != getArchPtrSize(tt))
- diags.Report(clang::diag::err_drv_incompatible_omp_arch)
- << arg->getValue(i) << t.str();
- else
- res.getLangOpts().OMPTargetTriples.push_back(tt);
- }
- }
- return !diags.hasUncompilableErrorOccurred();
-}
-
-/// Parses signed integer overflow options and populates the
-/// CompilerInvocation accordingly.
-/// Returns false if new errors are generated.
-///
-/// \param [out] invoc Stores the processed arguments
-/// \param [in] args The compiler invocation arguments to parse
-/// \param [out] diags DiagnosticsEngine to report erros with
-static bool parseIntegerOverflowArgs(CompilerInvocation &invoc,
- llvm::opt::ArgList &args,
- clang::DiagnosticsEngine &diags) {
- Fortran::common::LangOptions &opts = invoc.getLangOpts();
-
- if (args.getLastArg(clang::options::OPT_fwrapv))
- opts.setSignedOverflowBehavior(Fortran::common::LangOptions::SOB_Defined);
-
- return true;
-}
-
-/// Set the IEEE Floating point rounding modes, underflow mode and halting mode.
-///
-/// Initial halting mode:
-/// -ffpe-trap= sets the initial floating-point exception halting mode for the
-/// main program. Only the last -ffpe-trap= on the command line is effective.
-/// The value is a comma-separated set of exception mnemonics: "invalid",
-/// "zero", "overflow", "underflow", and "inexact" correspond to the Fortran
-/// 2023 IEEE_FLAG_TYPE values (F2023 17.2), and "denormal" is a non-standard,
-/// gfortran-compatible extension. "none", as well as an empty list, requests no
-/// halting and resets any earlier request.
-///
-/// TODO:
-/// Rounding modes
-/// Underflow mode
-///
-/// The value and the target-support warnings are validated in the driver (see
-/// addIEEEFPModesOptions() in clang/lib/Driver/ToolChains/Flang.cpp);
-/// here we only translate the already-validated list, so an unrecognized
-/// mnemonic maps to 0 and is ignored rather than re-diagnosed.
-static void setIEEEFPModesArgs(Fortran::common::LangOptions &opts,
- llvm::opt::ArgList &args) {
- const llvm::opt::Arg *a = args.getLastArg(clang::options::OPT_ffpe_trap_EQ);
- if (!a)
- return;
-
- using LangOptions = Fortran::common::LangOptions;
- unsigned traps = 0;
- llvm::SmallVector<llvm::StringRef> trapList;
- llvm::StringRef(a->getValue())
- .split(trapList, ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
- for (llvm::StringRef trap : trapList) {
- if (trap == "none") {
- // Reset to no halting; a later mnemonic can re-enable.
- traps = 0;
- continue;
- }
- traps |= llvm::StringSwitch<unsigned>(trap)
- .Case("invalid", LangOptions::FPE_Invalid)
- .Case("denormal", LangOptions::FPE_Denormal)
- .Case("zero", LangOptions::FPE_DivByZero)
- .Case("overflow", LangOptions::FPE_Overflow)
- .Case("underflow", LangOptions::FPE_Underflow)
- .Case("inexact", LangOptions::FPE_Inexact)
- .Default(0);
- }
- opts.FPExceptionTraps = traps;
+ return diags.getNumErrors() == numErrorsBefore;
}
/// Parses all floating point related arguments and populates the
@@ -1541,17 +846,17 @@ static void setIEEEFPModesArgs(Fortran::common::LangOptions &opts,
static bool parseFloatingPointArgs(CompilerInvocation &invoc,
llvm::opt::ArgList &args,
clang::DiagnosticsEngine &diags) {
- Fortran::common::LangOptions &opts = invoc.getLangOpts();
+ LangOptions &opts = invoc.getLangOpts();
if (const llvm::opt::Arg *a =
- args.getLastArg(clang::options::OPT_ffp_contract)) {
+ args.getLastArg(clang::driver::options::OPT_ffp_contract)) {
const llvm::StringRef val = a->getValue();
- enum Fortran::common::LangOptions::FPModeKind fpContractMode;
+ enum LangOptions::FPModeKind fpContractMode;
if (val == "off")
- fpContractMode = Fortran::common::LangOptions::FPM_Off;
+ fpContractMode = LangOptions::FPM_Off;
else if (val == "fast")
- fpContractMode = Fortran::common::LangOptions::FPM_Fast;
+ fpContractMode = LangOptions::FPM_Fast;
else {
diags.Report(clang::diag::err_drv_unsupported_option_argument)
<< a->getSpelling() << val;
@@ -1561,200 +866,48 @@ static bool parseFloatingPointArgs(CompilerInvocation &invoc,
opts.setFPContractMode(fpContractMode);
}
- if (args.getLastArg(clang::options::OPT_menable_no_infs)) {
+ if (args.getLastArg(clang::driver::options::OPT_menable_no_infinities)) {
opts.NoHonorInfs = true;
}
- if (args.getLastArg(clang::options::OPT_menable_no_nans)) {
+ if (args.getLastArg(clang::driver::options::OPT_menable_no_nans)) {
opts.NoHonorNaNs = true;
}
- if (args.getLastArg(clang::options::OPT_fapprox_func)) {
+ if (args.getLastArg(clang::driver::options::OPT_fapprox_func)) {
opts.ApproxFunc = true;
}
- if (args.getLastArg(clang::options::OPT_fno_signed_zeros)) {
+ if (args.getLastArg(clang::driver::options::OPT_fno_signed_zeros)) {
opts.NoSignedZeros = true;
}
- if (args.getLastArg(clang::options::OPT_mreassociate)) {
+ if (args.getLastArg(clang::driver::options::OPT_mreassociate)) {
opts.AssociativeMath = true;
}
- if (args.getLastArg(clang::options::OPT_freciprocal_math)) {
+ if (args.getLastArg(clang::driver::options::OPT_freciprocal_math)) {
opts.ReciprocalMath = true;
}
- if (args.getLastArg(clang::options::OPT_ffast_math)) {
+ if (args.getLastArg(clang::driver::options::OPT_ffast_math)) {
opts.NoHonorInfs = true;
opts.NoHonorNaNs = true;
opts.AssociativeMath = true;
opts.ReciprocalMath = true;
opts.ApproxFunc = true;
opts.NoSignedZeros = true;
- opts.FastRealMod = true;
- opts.setFPContractMode(Fortran::common::LangOptions::FPM_Fast);
- }
-
- if (llvm::opt::Arg *arg =
- args.getLastArg(clang::options::OPT_ffast_real_mod,
- clang::options::OPT_fno_fast_real_mod)) {
- if (arg->getOption().matches(clang::options::OPT_ffast_real_mod))
- opts.FastRealMod = true;
- if (arg->getOption().matches(clang::options::OPT_fno_fast_real_mod))
- opts.FastRealMod = false;
- }
-
- if (args.getLastArg(clang::options::OPT_fcheck_integer_mod_zero_divisor))
- opts.CheckIntegerModZeroDivisor = true;
-
- // Set the initial IEEE floating point modes
- setIEEEFPModesArgs(opts, args);
-
- return true;
-}
-
-/// Parses vscale range options and populates the CompilerInvocation
-/// accordingly.
-/// Returns false if new errors are generated.
-///
-/// \param [out] invoc Stores the processed arguments
-/// \param [in] args The compiler invocation arguments to parse
-/// \param [out] diags DiagnosticsEngine to report erros with
-static bool parseVScaleArgs(CompilerInvocation &invoc, llvm::opt::ArgList &args,
- clang::DiagnosticsEngine &diags) {
- const auto *vscaleMin = args.getLastArg(clang::options::OPT_mvscale_min_EQ);
- const auto *vscaleMax = args.getLastArg(clang::options::OPT_mvscale_max_EQ);
-
- if (!vscaleMin && !vscaleMax)
- return true;
-
- llvm::Triple triple = llvm::Triple(invoc.getTargetOpts().triple);
- if (!triple.isAArch64() && !triple.isRISCV()) {
- const unsigned diagID =
- diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
- "`-mvscale-max` and `-mvscale-min` are not "
- "supported for this architecture: %0");
- diags.Report(diagID) << triple.getArchName();
- return false;
- }
-
- Fortran::common::LangOptions &opts = invoc.getLangOpts();
- if (vscaleMin) {
- llvm::StringRef argValue = llvm::StringRef(vscaleMin->getValue());
- unsigned vscaleMinVal;
- if (argValue.getAsInteger(/*Radix=*/10, vscaleMinVal)) {
- diags.Report(clang::diag::err_drv_unsupported_option_argument)
- << vscaleMax->getSpelling() << argValue;
- return false;
- }
- opts.VScaleMin = vscaleMinVal;
- }
-
- if (vscaleMax) {
- llvm::StringRef argValue = llvm::StringRef(vscaleMax->getValue());
- unsigned vscaleMaxVal;
- if (argValue.getAsInteger(/*Radix=w*/ 10, vscaleMaxVal)) {
- diags.Report(clang::diag::err_drv_unsupported_option_argument)
- << vscaleMax->getSpelling() << argValue;
- return false;
- }
- opts.VScaleMax = vscaleMaxVal;
- }
- return true;
-}
-
-static bool parseLinkerOptionsArgs(CompilerInvocation &invoc,
- llvm::opt::ArgList &args,
- clang::DiagnosticsEngine &diags) {
- llvm::Triple triple = llvm::Triple(invoc.getTargetOpts().triple);
- CodeGenOptions &opts = invoc.getCodeGenOpts();
-
- // TODO: support --dependent-lib on other platforms when MLIR supports
- // !llvm.dependent.lib
- if (args.hasArg(clang::options::OPT_dependent_lib) && !triple.isOSWindows()) {
- const unsigned diagID =
- diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
- "--dependent-lib is only supported on Windows");
- diags.Report(diagID);
- return false;
- }
-
- opts.DependentLibs = args.getAllArgValues(clang::options::OPT_dependent_lib);
-
- // -flto=full/thin option.
- if (const llvm::opt::Arg *a = args.getLastArg(clang::options::OPT_flto_EQ)) {
- llvm::StringRef s = a->getValue();
- assert((s == "full" || s == "thin") && "Unknown LTO mode.");
- if (s == "full")
- opts.PrepareForFullLTO = true;
- else
- opts.PrepareForThinLTO = true;
+ opts.setFPContractMode(LangOptions::FPM_Fast);
}
- // -fsplit-lto-unit option
- if (args.hasArg(clang::options::OPT_fsplit_lto_unit))
- opts.EnableSplitLTOUnit = true;
-
- // -ffat-lto-objects
- if (const llvm::opt::Arg *arg =
- args.getLastArg(clang::options::OPT_ffat_lto_objects,
- clang::options::OPT_fno_fat_lto_objects)) {
- opts.PrepareForFatLTO =
- arg->getOption().matches(clang::options::OPT_ffat_lto_objects);
- if (opts.PrepareForFatLTO) {
- assert((opts.PrepareForFullLTO || opts.PrepareForThinLTO) &&
- "Unknown LTO mode");
-
- if (!triple.isOSBinFormatELF())
- diags.Report(clang::diag::err_drv_unsupported_opt_for_target)
- << arg->getAsString(args) << triple.getTriple();
- }
- }
return true;
}
-static bool parseLangOptionsArgs(CompilerInvocation &invoc,
- llvm::opt::ArgList &args,
- clang::DiagnosticsEngine &diags) {
- bool success = true;
-
- success &= parseIntegerOverflowArgs(invoc, args, diags);
- success &= parseFloatingPointArgs(invoc, args, diags);
- success &= parseVScaleArgs(invoc, args, diags);
-
- return success;
-}
-
-// Copied from clang/lib/Frontend/CompilerInvocation.cpp.
-static void addDiagnosticArgs(llvm::opt::ArgList &args,
- llvm::opt::OptSpecifier group,
- llvm::opt::OptSpecifier groupWithValue,
- std::vector<std::string> &diagnostics) {
- for (auto *a : args.filtered(group)) {
- if (a->getOption().getKind() == llvm::opt::Option::FlagClass) {
- // The argument is a pure flag (such as OPT_Wall or OPT_Wdeprecated). Add
- // its name (minus the "W" or "R" at the beginning) to the diagnostics.
- diagnostics.push_back(
- std::string(a->getOption().getName().drop_front(1)));
- } else if (a->getOption().matches(groupWithValue)) {
- // This is -Wfoo= or -Rfoo=, where foo is the name of the diagnostic
- // group. Add only the group name to the diagnostics.
- diagnostics.push_back(
- std::string(a->getOption().getName().drop_front(1).rtrim("=-")));
- } else {
- // Otherwise, add its value (for OPT_W_Joined and similar).
- diagnostics.push_back(a->getValue());
- }
- }
-}
-
bool CompilerInvocation::createFromArgs(
- CompilerInvocation &invoc, llvm::ArrayRef<const char *> commandLineArgs,
+ CompilerInvocation &res, llvm::ArrayRef<const char *> commandLineArgs,
clang::DiagnosticsEngine &diags, const char *argv0) {
bool success = true;
- clang::DiagnosticOptions &diagOpts = diags.getDiagnosticOptions();
// Set the default triple for this CompilerInvocation. This might be
// overridden by users with `-triple` (see the call to `ParseTargetArgs`
@@ -1762,15 +915,15 @@ bool CompilerInvocation::createFromArgs(
// NOTE: Like in Clang, it would be nice to use option marshalling
// for this so that the entire logic for setting-up the triple is in one
// place.
- invoc.getTargetOpts().triple =
+ res.getTargetOpts().triple =
llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple());
// Parse the arguments
- const llvm::opt::OptTable &opts = clang::getDriverOptTable();
- llvm::opt::Visibility visibilityMask(clang::options::FC1Option);
+ const llvm::opt::OptTable &opts = clang::driver::getDriverOptTable();
+ const unsigned includedFlagsBitmask = clang::driver::options::FC1Option;
unsigned missingArgIndex, missingArgCount;
llvm::opt::InputArgList args = opts.ParseArgs(
- commandLineArgs, missingArgIndex, missingArgCount, visibilityMask);
+ commandLineArgs, missingArgIndex, missingArgCount, includedFlagsBitmask);
// Check for missing argument error.
if (missingArgCount) {
@@ -1780,10 +933,10 @@ bool CompilerInvocation::createFromArgs(
}
// Issue errors on unknown arguments
- for (const auto *a : args.filtered(clang::options::OPT_UNKNOWN)) {
+ for (const auto *a : args.filtered(clang::driver::options::OPT_UNKNOWN)) {
auto argString = a->getAsString(args);
std::string nearest;
- if (opts.findNearest(argString, nearest, visibilityMask) > 1)
+ if (opts.findNearest(argString, nearest, includedFlagsBitmask) > 1)
diags.Report(clang::diag::err_drv_unknown_argument) << argString;
else
diags.Report(clang::diag::err_drv_unknown_argument_with_suggestion)
@@ -1791,142 +944,43 @@ bool CompilerInvocation::createFromArgs(
success = false;
}
- // Handle -Wno-<warning> flags.
- addDiagnosticArgs(args, clang::options::OPT_W_Group,
- clang::options::OPT_W_value_Group, diagOpts.Warnings);
- auto vfs = llvm::vfs::getRealFileSystem();
- clang::ProcessWarningOptions(diags, diagOpts, *vfs, /*ReportDiags=*/false);
-
- // -fno-ppc-native-vector-element-order
- if (args.hasArg(clang::options::OPT_fno_ppc_native_vec_elem_order)) {
- invoc.loweringOpts.setNoPPCNativeVecElemOrder(true);
+ // -flang-experimental-hlfir
+ if (args.hasArg(clang::driver::options::OPT_flang_experimental_hlfir) ||
+ args.hasArg(clang::driver::options::OPT_emit_hlfir)) {
+ res.loweringOpts.setLowerToHighLevelFIR(true);
}
- // -f[no-]init-global-zero
- if (args.hasFlag(clang::options::OPT_finit_global_zero,
- clang::options::OPT_fno_init_global_zero,
- /*default=*/true))
- invoc.loweringOpts.setInitGlobalZero(true);
- else
- invoc.loweringOpts.setInitGlobalZero(false);
-
- // -finit-local=<zero|0x<hex>> and -finit-local-zero
- // (-finit-local-zero is an alias that the driver already expands to
- // -finit-local=zero, so we only need to handle OPT_finit_local_EQ here.)
- if (const llvm::opt::Arg *a =
- args.getLastArg(clang::options::OPT_finit_local_EQ)) {
- llvm::StringRef val = a->getValue();
- if (val == "zero") {
- invoc.loweringOpts.setInitLocalMode(Fortran::lower::InitLocalKind::Zero);
- } else if (val.starts_with("0x") || val.starts_with("0X")) {
- unsigned long long hexVal = 0;
- if (val.drop_front(2).getAsInteger(16, hexVal) || hexVal > 0xFF) {
- diags.Report(clang::diag::err_drv_invalid_value)
- << a->getAsString(args) << val;
- } else {
- invoc.loweringOpts.setInitLocalMode(Fortran::lower::InitLocalKind::Hex);
- invoc.loweringOpts.setInitLocalPattern(static_cast<uint8_t>(hexVal));
- }
- } else {
- diags.Report(clang::diag::err_drv_invalid_value)
- << a->getAsString(args) << val;
- }
+ if (args.hasArg(clang::driver::options::OPT_flang_experimental_polymorphism)) {
+ res.loweringOpts.setPolymorphicTypeImpl(true);
}
- // Preserve all the remark options requested, i.e. -Rpass, -Rpass-missed or
- // -Rpass-analysis. This will be used later when processing and outputting the
- // remarks generated by LLVM in ExecuteCompilerInvocation.cpp.
- for (auto *a : args.filtered(clang::options::OPT_R_Group)) {
- if (a->getOption().matches(clang::options::OPT_R_value_Group))
- // This is -Rfoo=, where foo is the name of the diagnostic
- // group. Add only the remark option name to the diagnostics. e.g. for
- // -Rpass= we will add the string "pass".
- invoc.getDiagnosticOpts().Remarks.push_back(
- std::string(a->getOption().getName().drop_front(1).rtrim("=-")));
- else
- // If no regex was provided, add the provided value, e.g. for -Rpass add
- // the string "pass".
- invoc.getDiagnosticOpts().Remarks.push_back(a->getValue());
- }
-
- // -frealloc-lhs is the default.
- if (!args.hasFlag(clang::options::OPT_frealloc_lhs,
- clang::options::OPT_fno_realloc_lhs, true)) {
- invoc.loweringOpts.setReallocateLHS(false);
- invoc.getLangOpts().NoReallocateLHS = true;
- }
-
- invoc.loweringOpts.setRepackArrays(args.hasFlag(
- clang::options::OPT_frepack_arrays, clang::options::OPT_fno_repack_arrays,
- /*default=*/false));
- invoc.loweringOpts.setStackRepackArrays(
- args.hasFlag(clang::options::OPT_fstack_repack_arrays,
- clang::options::OPT_fno_stack_repack_arrays,
- /*default=*/false));
- if (auto *arg =
- args.getLastArg(clang::options::OPT_frepack_arrays_contiguity_EQ))
- invoc.loweringOpts.setRepackArraysWhole(arg->getValue() ==
- llvm::StringRef{"whole"});
-
- // -f[no-]openacc-combined-loop-firstprivate
- invoc.loweringOpts.setOpenACCCombinedLoopFirstprivate(
- args.hasFlag(clang::options::OPT_fopenacc_combined_loop_firstprivate,
- clang::options::OPT_fno_openacc_combined_loop_firstprivate,
- /*default=*/true));
-
- // -f[no-]openacc-acc-kernels-do-concurrent-independent
- invoc.loweringOpts.setOpenACCKernelsDoConcurrentIndependent(args.hasFlag(
- clang::options::OPT_fopenacc_acc_kernels_do_concurrent_independent,
- clang::options::OPT_fno_openacc_acc_kernels_do_concurrent_independent,
- /*default=*/true));
-
- if (auto *arg = args.getLastArg(clang::options::OPT_ffp_maxmin_behavior_EQ)) {
- auto value = Fortran::common::parseFPMaxminBehavior(arg->getValue());
- invoc.getCodeGenOpts().setFPMaxminBehavior(value);
- invoc.loweringOpts.setFPMaxminBehavior(value);
- }
-
- success &= parseFrontendArgs(invoc.getFrontendOpts(), args, diags);
- parseTargetArgs(invoc.getTargetOpts(), args);
- parsePreprocessorArgs(invoc.getPreprocessorOpts(), args);
- parseCodeGenArgs(invoc.getCodeGenOpts(), args, diags);
- success &= parseDoConcurrentMapping(invoc.getCodeGenOpts(), args, diags);
- success &= parseDebugArgs(invoc.getCodeGenOpts(), args, diags);
-
- // Enable USE statement preservation for debug info if debug level is above
- // LineTablesOnly.
- using DebugInfoKind = llvm::codegenoptions::DebugInfoKind;
- DebugInfoKind debugLevel = invoc.getCodeGenOpts().getDebugInfo();
- invoc.loweringOpts.setPreserveUseDebugInfo(
- debugLevel > DebugInfoKind::DebugLineTablesOnly);
-
- success &= parseVectorLibArg(invoc.getCodeGenOpts(), args, diags);
- success &= parseSemaArgs(invoc, args, diags);
- success &= parseDialectArgs(invoc, args, diags);
- success &= parseOpenMPArgs(invoc, args, diags);
- success &= parseDiagArgs(invoc, args, diags);
+ success &= parseFrontendArgs(res.getFrontendOpts(), args, diags);
+ parseTargetArgs(res.getTargetOpts(), args);
+ parsePreprocessorArgs(res.getPreprocessorOpts(), args);
+ parseCodeGenArgs(res.getCodeGenOpts(), args, diags);
+ success &= parseDebugArgs(res.getCodeGenOpts(), args, diags);
+ success &= parseSemaArgs(res, args, diags);
+ success &= parseDialectArgs(res, args, diags);
+ success &= parseDiagArgs(res, args, diags);
// Collect LLVM (-mllvm) and MLIR (-mmlir) options.
// NOTE: Try to avoid adding any options directly to `llvmArgs` or
// `mlirArgs`. Instead, you can use
// * `-mllvm <your-llvm-option>`, or
// * `-mmlir <your-mlir-option>`.
- invoc.frontendOpts.llvmArgs = args.getAllArgValues(clang::options::OPT_mllvm);
- invoc.frontendOpts.mlirArgs = args.getAllArgValues(clang::options::OPT_mmlir);
-
- if (args.hasArg(clang::options::OPT_foffload_device))
- invoc.getLangOpts().OffloadDevice = 1;
-
- success &= parseLangOptionsArgs(invoc, args, diags);
+ res.frontendOpts.llvmArgs =
+ args.getAllArgValues(clang::driver::options::OPT_mllvm);
+ res.frontendOpts.mlirArgs =
+ args.getAllArgValues(clang::driver::options::OPT_mmlir);
- success &= parseLinkerOptionsArgs(invoc, args, diags);
+ success &= parseFloatingPointArgs(res, args, diags);
// Set the string to be used as the return value of the COMPILER_OPTIONS
// intrinsic of iso_fortran_env. This is either passed in from the parent
// compiler driver invocation with an environment variable, or failing that
// set to the command line arguments of the frontend driver invocation.
- invoc.allCompilerInvocOpts = std::string();
- llvm::raw_string_ostream os(invoc.allCompilerInvocOpts);
+ res.allCompilerInvocOpts = std::string();
+ llvm::raw_string_ostream os(res.allCompilerInvocOpts);
char *compilerOptsEnv = std::getenv("FLANG_COMPILER_OPTIONS_STRING");
if (compilerOptsEnv != nullptr) {
os << compilerOptsEnv;
@@ -1938,12 +992,6 @@ bool CompilerInvocation::createFromArgs(
}
}
- // Process the timing-related options.
- if (args.hasArg(clang::options::OPT_ftime_report))
- invoc.enableTimers = true;
-
- invoc.setArgv0(argv0);
-
return success;
}
@@ -1984,6 +1032,10 @@ void CompilerInvocation::setDefaultFortranOpts() {
std::vector<std::string> searchDirectories{"."s};
fortranOptions.searchDirectories = searchDirectories;
+ // Add the location of omp_lib.h to the search directories. Currently this is
+ // identical to the modules' directory.
+ fortranOptions.searchDirectories.emplace_back(getOpenMPHeadersDir());
+
fortranOptions.isFixedForm = false;
}
@@ -2002,20 +1054,6 @@ void CompilerInvocation::setDefaultPredefinitions() {
fortranOptions.predefinitions.emplace_back("__flang_patchlevel__",
FLANG_VERSION_PATCHLEVEL_STRING);
- // Add predefinitions based on the relocation model
- if (unsigned PICLevel = getCodeGenOpts().PICLevel) {
- fortranOptions.predefinitions.emplace_back("__PIC__",
- std::to_string(PICLevel));
- fortranOptions.predefinitions.emplace_back("__pic__",
- std::to_string(PICLevel));
- if (getCodeGenOpts().IsPIE) {
- fortranOptions.predefinitions.emplace_back("__PIE__",
- std::to_string(PICLevel));
- fortranOptions.predefinitions.emplace_back("__pie__",
- std::to_string(PICLevel));
- }
- }
-
// Add predefinitions based on extensions enabled
if (frontendOptions.features.IsEnabled(
Fortran::common::LanguageFeature::OpenACC)) {
@@ -2023,48 +1061,13 @@ void CompilerInvocation::setDefaultPredefinitions() {
}
if (frontendOptions.features.IsEnabled(
Fortran::common::LanguageFeature::OpenMP)) {
- Fortran::common::setOpenMPMacro(
- static_cast<unsigned>(getLangOpts().getOpenMPVersion()),
- fortranOptions.predefinitions);
- }
-
- if (frontendOptions.features.IsEnabled(
- Fortran::common::LanguageFeature::CUDA)) {
- fortranOptions.predefinitions.emplace_back("_CUDA", "1");
+ Fortran::common::setOpenMPMacro(getLangOpts().OpenMPVersion,
+ fortranOptions.predefinitions);
}
-
llvm::Triple targetTriple{llvm::Triple(this->targetOpts.triple)};
- if (targetTriple.isOSLinux()) {
- fortranOptions.predefinitions.emplace_back("__linux__", "1");
- } else if (targetTriple.isOSAIX()) {
- fortranOptions.predefinitions.emplace_back("_AIX", "1");
- }
-
- switch (targetTriple.getArch()) {
- default:
- break;
- case llvm::Triple::ArchType::x86_64:
+ if (targetTriple.getArch() == llvm::Triple::ArchType::x86_64) {
fortranOptions.predefinitions.emplace_back("__x86_64__", "1");
fortranOptions.predefinitions.emplace_back("__x86_64", "1");
- break;
- case llvm::Triple::ArchType::ppc:
- case llvm::Triple::ArchType::ppc64:
- case llvm::Triple::ArchType::ppcle:
- case llvm::Triple::ArchType::ppc64le:
- // '__powerpc__' is a generic macro for any PowerPC.
- fortranOptions.predefinitions.emplace_back("__powerpc__", "1");
- if (targetTriple.isOSAIX() && targetTriple.isArch64Bit()) {
- fortranOptions.predefinitions.emplace_back("__64BIT__", "1");
- }
- break;
- case llvm::Triple::ArchType::aarch64:
- fortranOptions.predefinitions.emplace_back("__aarch64__", "1");
- fortranOptions.predefinitions.emplace_back("__aarch64", "1");
- break;
- case llvm::Triple::ArchType::systemz:
- fortranOptions.predefinitions.emplace_back("__s390x__", "1");
- fortranOptions.predefinitions.emplace_back("__s390x", "1");
- break;
}
}
@@ -2080,10 +1083,6 @@ void CompilerInvocation::setFortranOpts() {
}
fortranOptions.fixedFormColumns = frontendOptions.fixedFormColumns;
- // -E
- fortranOptions.prescanAndReformat =
- frontendOptions.programAction == PrintPreprocessedInput;
-
fortranOptions.features = frontendOptions.features;
fortranOptions.encoding = frontendOptions.encoding;
@@ -2099,15 +1098,8 @@ void CompilerInvocation::setFortranOpts() {
preprocessorOptions.searchDirectoriesFromIntrModPath.begin(),
preprocessorOptions.searchDirectoriesFromIntrModPath.end());
- // Add the ordered list of -fintrinsic-modules-path
- fortranOptions.intrinsicModuleDirectories.insert(
- fortranOptions.intrinsicModuleDirectories.end(),
- preprocessorOptions.searchDirectoriesFromIntrModPath.begin(),
- preprocessorOptions.searchDirectoriesFromIntrModPath.end());
-
// Add the default intrinsic module directory
- fortranOptions.intrinsicModuleDirectories.emplace_back(
- getIntrinsicDir(getArgv0()));
+ fortranOptions.intrinsicModuleDirectories.emplace_back(getIntrinsicDir());
// Add the directory supplied through -J/-module-dir to the list of search
// directories
@@ -2123,39 +1115,40 @@ void CompilerInvocation::setFortranOpts() {
if (frontendOptions.needProvenanceRangeToCharBlockMappings)
fortranOptions.needProvenanceRangeToCharBlockMappings = true;
- fortranOptions.features = frontendOptions.features;
+ if (getEnableConformanceChecks())
+ fortranOptions.features.WarnOnAllNonstandard();
+
+ if (getEnableUsageChecks())
+ fortranOptions.features.WarnOnAllUsage();
}
-std::unique_ptr<Fortran::semantics::SemanticsContext>
-CompilerInvocation::getSemanticsCtx(
- Fortran::parser::AllCookedSources &allCookedSources,
- const llvm::TargetMachine &targetMachine) {
+void CompilerInvocation::setSemanticsOpts(
+ Fortran::parser::AllCookedSources &allCookedSources) {
auto &fortranOptions = getFortranOpts();
- auto semanticsContext = std::make_unique<semantics::SemanticsContext>(
- getDefaultKinds(), fortranOptions.features, getLangOpts(),
- allCookedSources, getCodeGenOpts().getFPMaxminBehavior());
+ semanticsContext = std::make_unique<semantics::SemanticsContext>(
+ getDefaultKinds(), fortranOptions.features, allCookedSources);
semanticsContext->set_moduleDirectory(getModuleDir())
.set_searchDirectories(fortranOptions.searchDirectories)
.set_intrinsicModuleDirectories(fortranOptions.intrinsicModuleDirectories)
- .set_maxErrors(getMaxErrors())
.set_warningsAreErrors(getWarnAsErr())
- .set_moduleFileSuffix(getModuleFileSuffix())
- .set_underscoring(getCodeGenOpts().Underscoring)
- .set_openAccDefaultNoneScalarsStrictDisableOption(
- clang::getDriverOptTable()
- .getOptionPrefixedName(
- clang::options::OPT_fno_openacc_default_none_scalars_strict)
- .str())
- .set_targetTriple(targetMachine.getTargetTriple().str())
- .set_targetFeatures(targetMachine.getTargetFeatureString().str());
-
- std::string compilerVersion = Fortran::common::getFlangFullVersion();
- Fortran::tools::setUpTargetCharacteristics(
- semanticsContext->targetCharacteristics(), targetMachine, getTargetOpts(),
- compilerVersion, allCompilerInvocOpts);
- return semanticsContext;
+ .set_moduleFileSuffix(getModuleFileSuffix());
+
+ llvm::Triple targetTriple{llvm::Triple(this->targetOpts.triple)};
+ // FIXME: Handle real(3) ?
+ if (targetTriple.getArch() != llvm::Triple::ArchType::x86_64) {
+ semanticsContext->targetCharacteristics().DisableType(
+ Fortran::common::TypeCategory::Real, /*kind=*/10);
+ }
+
+ std::string version = Fortran::common::getFlangFullVersion();
+ semanticsContext->targetCharacteristics()
+ .set_compilerOptionsString(allCompilerInvocOpts)
+ .set_compilerVersionString(version);
+
+ if (targetTriple.isPPC())
+ semanticsContext->targetCharacteristics().set_isPPC(true);
}
/// Set \p loweringOptions controlling lowering behavior based
@@ -2165,33 +1158,19 @@ void CompilerInvocation::setLoweringOptions() {
// Lower TRANSPOSE as a runtime call under -O0.
loweringOpts.setOptimizeTranspose(codegenOpts.OptimizationLevel > 0);
- loweringOpts.setUnderscoring(codegenOpts.Underscoring);
- loweringOpts.setSkipExternalRttiDefinition(skipExternalRttiDefinition);
-
- const Fortran::common::LangOptions &langOptions = getLangOpts();
- loweringOpts.setIntegerWrapAround(langOptions.getSignedOverflowBehavior() ==
- Fortran::common::LangOptions::SOB_Defined);
- loweringOpts.setProtectParens(codegenOpts.ProtectParens);
- loweringOpts.setSplitSumExpressionTree(codegenOpts.SplitSumExpressionTree);
+
+ const LangOptions &langOptions = getLangOpts();
Fortran::common::MathOptionsBase &mathOpts = loweringOpts.getMathOptions();
// TODO: when LangOptions are finalized, we can represent
// the math related options using Fortran::commmon::MathOptionsBase,
// so that we can just copy it into LoweringOptions.
mathOpts
.setFPContractEnabled(langOptions.getFPContractMode() ==
- Fortran::common::LangOptions::FPM_Fast)
+ LangOptions::FPM_Fast)
.setNoHonorInfs(langOptions.NoHonorInfs)
.setNoHonorNaNs(langOptions.NoHonorNaNs)
.setApproxFunc(langOptions.ApproxFunc)
.setNoSignedZeros(langOptions.NoSignedZeros)
.setAssociativeMath(langOptions.AssociativeMath)
.setReciprocalMath(langOptions.ReciprocalMath);
-
- if (codegenOpts.getComplexRange() ==
- CodeGenOptions::ComplexRangeKind::CX_Improved ||
- codegenOpts.getComplexRange() ==
- CodeGenOptions::ComplexRangeKind::CX_Basic)
- loweringOpts.setComplexDivisionToRuntime(false);
-
- loweringOpts.setFPExceptionTraps(langOptions.FPExceptionTraps);
}
More information about the flang-commits
mailing list