[llvm-branch-commits] [clang] a1a0f84 - [ClassicFlang] Port flang-driver release_90 changes to release/10.x
Bryan Chan via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Jun 24 08:41:01 PDT 2020
Author: Bryan Chan
Date: 2020-06-23T11:27:10-04:00
New Revision: a1a0f84b986d6a3cc7b81edb9ff20a78a0c2aca2
URL: https://github.com/llvm/llvm-project/commit/a1a0f84b986d6a3cc7b81edb9ff20a78a0c2aca2
DIFF: https://github.com/llvm/llvm-project/commit/a1a0f84b986d6a3cc7b81edb9ff20a78a0c2aca2.diff
LOG: [ClassicFlang] Port flang-driver release_90 changes to release/10.x
Cherry-picked c51f89679135f84675f492d560ec5535c2000cfe by Varun Jayathirtha,
and resolved merge conflicts.
To avoid conflicts with the new Flang, lib/Driver/ToolChains/Flang.{cpp,h}
have been renamed to Flang1.{cpp,h}, and the USE_CLASSIC_FLANG macro is
introduced to select which incarnation of Flang to build. The macro is set
by running CMake with -DLLVM_ENABLE_CLASSIC_FLANG.
Added:
clang/lib/Driver/ToolChains/Flang1.cpp
clang/lib/Driver/ToolChains/Flang1.h
Modified:
clang/CMakeLists.txt
clang/include/clang/Basic/CodeGenOptions.def
clang/include/clang/Basic/CodeGenOptions.h
clang/include/clang/Basic/DiagnosticDriverKinds.td
clang/include/clang/Basic/MacroBuilder.h
clang/include/clang/Basic/Sanitizers.def
clang/include/clang/Driver/Action.h
clang/include/clang/Driver/Options.td
clang/include/clang/Driver/Phases.h
clang/include/clang/Driver/ToolChain.h
clang/include/clang/Driver/Types.def
clang/include/clang/Driver/Types.h
clang/include/clang/Frontend/Utils.h
clang/lib/CodeGen/BackendUtil.cpp
clang/lib/CodeGen/CodeGenAction.cpp
clang/lib/Driver/Action.cpp
clang/lib/Driver/CMakeLists.txt
clang/lib/Driver/Driver.cpp
clang/lib/Driver/Phases.cpp
clang/lib/Driver/ToolChain.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Driver/ToolChains/CommonArgs.cpp
clang/lib/Driver/ToolChains/CommonArgs.h
clang/lib/Driver/ToolChains/Cuda.cpp
clang/lib/Driver/ToolChains/Cuda.h
clang/lib/Driver/ToolChains/Gnu.cpp
clang/lib/Driver/ToolChains/Linux.cpp
clang/lib/Driver/ToolChains/Linux.h
clang/lib/Driver/Types.cpp
clang/lib/Frontend/CompilerInvocation.cpp
clang/lib/Frontend/InitPreprocessor.cpp
clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
clang/tools/driver/CMakeLists.txt
Removed:
################################################################################
diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt
index dc1413f4b597..d7ebdb48f5b5 100644
--- a/clang/CMakeLists.txt
+++ b/clang/CMakeLists.txt
@@ -458,6 +458,16 @@ endif()
add_definitions( -D_GNU_SOURCE )
+option(LLVM_ENABLE_CLASSIC_FLANG "Build support for classic Flang instead of the new built-in Flang" OFF)
+if(LLVM_ENABLE_CLASSIC_FLANG)
+ add_definitions( -DUSE_CLASSIC_FLANG )
+endif()
+
+option(FLANG_LLVM_EXTENSIONS "enable the Flang LLVM extensions" OFF)
+if(FLANG_LLVM_EXTENSIONS)
+ add_definitions( -DFLANG_LLVM_EXTENSIONS )
+endif()
+
option(CLANG_BUILD_TOOLS
"Build the Clang tools. If OFF, just generate build targets." ON)
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 1ecae98b13b1..5ce83d904387 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -329,7 +329,7 @@ CODEGENOPT(CodeViewGHash, 1, 0)
ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NormalInlining)
// Vector functions library to use.
-ENUM_CODEGENOPT(VecLib, VectorLibrary, 2, NoLibrary)
+ENUM_CODEGENOPT(VecLib, VectorLibrary, 3, NoLibrary)
/// The default TLS model to use.
ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel)
diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index 21ac54e8ee12..520adf446ea6 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -55,6 +55,9 @@ class CodeGenOptions : public CodeGenOptionsBase {
NoLibrary, // Don't use any vector library.
Accelerate, // Use the Accelerate framework.
MASSV, // IBM MASS vector library.
+#ifdef FLANG_LLVM_EXTENSIONS
+ PGMATH, // PGI math library.
+#endif
SVML // Intel short vector math library.
};
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 48ece91d3c45..8580c5933524 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -73,6 +73,10 @@ def err_drv_invalid_pgo_instrumentor : Error<
"invalid PGO instrumentor in argument '%0'">;
def err_drv_invalid_rtlib_name : Error<
"invalid runtime library name in argument '%0'">;
+def err_drv_invalid_allocatable_mode : Error<
+ "invalid semantic mode for assignments to allocatables in argument '%0'">;
+def err_drv_unsupported_fixed_line_length : Error<
+ "unsupported fixed-format line length in argument '%0'">;
def err_drv_unsupported_rtlib_for_platform : Error<
"unsupported runtime library '%0' for platform '%1'">;
def err_drv_invalid_unwindlib_name : Error<
@@ -252,6 +256,8 @@ def err_drv_unsupported_embed_bitcode
: Error<"%0 is not supported with -fembed-bitcode">;
def err_drv_bitcode_unsupported_on_toolchain : Error<
"-fembed-bitcode is not supported on versions of iOS prior to 6.0">;
+def err_drv_clang_unsupported_minfo_arg : Error<
+ "'%0' option does not support '%1' value">;
def err_drv_invalid_malign_branch_EQ : Error<
"invalid argument '%0' to -malign-branch=; each element must be one of: %1">;
diff --git a/clang/include/clang/Basic/MacroBuilder.h b/clang/include/clang/Basic/MacroBuilder.h
index 96e67cbbfa3f..a5fb7e73f287 100644
--- a/clang/include/clang/Basic/MacroBuilder.h
+++ b/clang/include/clang/Basic/MacroBuilder.h
@@ -26,7 +26,7 @@ class MacroBuilder {
MacroBuilder(raw_ostream &Output) : Out(Output) {}
/// Append a \#define line for macro of the form "\#define Name Value\n".
- void defineMacro(const Twine &Name, const Twine &Value = "1") {
+ virtual void defineMacro(const Twine &Name, const Twine &Value = "1") {
Out << "#define " << Name << ' ' << Value << '\n';
}
diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def
index 0037cc2146f2..0f51cd0e001e 100644
--- a/clang/include/clang/Basic/Sanitizers.def
+++ b/clang/include/clang/Basic/Sanitizers.def
@@ -104,6 +104,8 @@ SANITIZER("signed-integer-overflow", SignedIntegerOverflow)
SANITIZER("unreachable", Unreachable)
SANITIZER("vla-bound", VLABound)
SANITIZER("vptr", Vptr)
+// fortran contiguous pointer checks
+SANITIZER("discontiguous", Discontiguous)
// IntegerSanitizer
SANITIZER("unsigned-integer-overflow", UnsignedIntegerOverflow)
diff --git a/clang/include/clang/Driver/Action.h b/clang/include/clang/Driver/Action.h
index 8ccbb6c2bbfa..40ded1c839de 100644
--- a/clang/include/clang/Driver/Action.h
+++ b/clang/include/clang/Driver/Action.h
@@ -62,6 +62,7 @@ class Action {
AnalyzeJobClass,
MigrateJobClass,
CompileJobClass,
+ FortranFrontendJobClass,
BackendJobClass,
AssembleJobClass,
LinkJobClass,
@@ -454,6 +455,16 @@ class MigrateJobAction : public JobAction {
}
};
+class FortranFrontendJobAction : public JobAction {
+ void anchor() override;
+public:
+ FortranFrontendJobAction(Action *Input, types::ID OutputType);
+
+ static bool classof(const Action *A) {
+ return A->getKind() == FortranFrontendJobClass;
+ }
+};
+
class CompileJobAction : public JobAction {
void anchor() override;
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 0a60873443fc..2b0a00c570e0 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -254,7 +254,7 @@ class InternalDriverOpt : Group<internal_driver_Group>,
Flags<[DriverOption, HelpHidden]>;
def driver_mode : Joined<["--"], "driver-mode=">, Group<internal_driver_Group>,
Flags<[CoreOption, DriverOption, HelpHidden]>,
- HelpText<"Set the driver mode to either 'gcc', 'g++', 'cpp', or 'cl'">;
+ HelpText<"Set the driver mode to either 'gcc', 'g++', 'cpp', 'cl', or 'fortran'">;
def rsp_quoting : Joined<["--"], "rsp-quoting=">, Group<internal_driver_Group>,
Flags<[CoreOption, DriverOption, HelpHidden]>,
HelpText<"Set the rsp quoting to either 'posix', or 'windows'">;
@@ -1511,7 +1511,7 @@ def fno_experimental_new_pass_manager : Flag<["-"], "fno-experimental-new-pass-m
Group<f_clang_Group>, Flags<[CC1Option]>,
HelpText<"Disables an experimental new pass manager in LLVM.">;
def fveclib : Joined<["-"], "fveclib=">, Group<f_Group>, Flags<[CC1Option]>,
- HelpText<"Use the given vector functions library">, Values<"Accelerate,MASSV,SVML,none">;
+ HelpText<"Use the given vector functions library">, Values<"Accelerate,MASSV,PGMATH,SVML,none">;
def fno_lax_vector_conversions : Flag<["-"], "fno-lax-vector-conversions">, Group<f_Group>,
Alias<flax_vector_conversions_EQ>, AliasArgs<["none"]>;
def fno_merge_all_constants : Flag<["-"], "fno-merge-all-constants">, Group<f_Group>,
@@ -3318,11 +3318,19 @@ defm devirtualize : BooleanFFlag<"devirtualize">, Group<clang_ignored_gcc_optimi
defm devirtualize_speculatively : BooleanFFlag<"devirtualize-speculatively">,
Group<clang_ignored_gcc_optimization_f_Group>;
+// gfortran options that we recognize in the driver and pass along when
+// invoking GCC to compile Fortran code.
+def flang_rt_Group : OptionGroup<"Flang runtime library Group">;
+def pgi_fortran_Group : OptionGroup<"PGI Fortran compatibility Group">,
+ Flags<[HelpHidden]>;
+
// Generic gfortran options.
def A_DASH : Joined<["-"], "A-">, Group<gfortran_Group>;
def J : JoinedOrSeparate<["-"], "J">, Flags<[RenderJoined]>, Group<gfortran_Group>;
-def cpp : Flag<["-"], "cpp">, Group<gfortran_Group>;
-def nocpp : Flag<["-"], "nocpp">, Group<gfortran_Group>;
+def cpp : Flag<["-"], "cpp">, Group<gfortran_Group>,
+ HelpText<"Preprocess Fortran files">;
+def nocpp : Flag<["-"], "nocpp">, Group<gfortran_Group>,
+ HelpText<"Don't preprocess Fortran files">;
def static_libgfortran : Flag<["-"], "static-libgfortran">, Group<gfortran_Group>;
// "f" options with values for gfortran.
@@ -3330,7 +3338,8 @@ def fblas_matmul_limit_EQ : Joined<["-"], "fblas-matmul-limit=">, Group<gfortran
def fcheck_EQ : Joined<["-"], "fcheck=">, Group<gfortran_Group>;
def fcoarray_EQ : Joined<["-"], "fcoarray=">, Group<gfortran_Group>;
def fconvert_EQ : Joined<["-"], "fconvert=">, Group<gfortran_Group>;
-def ffixed_line_length_VALUE : Joined<["-"], "ffixed-line-length-">, Group<gfortran_Group>;
+def ffixed_line_length_VALUE : Joined<["-"], "ffixed-line-length-">, Group<gfortran_Group>,
+ HelpText<"Set line length in fixed-form format Fortran, current supporting only 72 and 132 characters">;
def ffpe_trap_EQ : Joined<["-"], "ffpe-trap=">, Group<gfortran_Group>;
def ffree_line_length_VALUE : Joined<["-"], "ffree-line-length-">, Group<gfortran_Group>;
def finit_character_EQ : Joined<["-"], "finit-character=">, Group<gfortran_Group>;
@@ -3343,12 +3352,17 @@ def fmax_stack_var_size_EQ : Joined<["-"], "fmax-stack-var-size=">, Group<gfortr
def fmax_subrecord_length_EQ : Joined<["-"], "fmax-subrecord-length=">, Group<gfortran_Group>;
def frecord_marker_EQ : Joined<["-"], "frecord-marker=">, Group<gfortran_Group>;
+// Define a group for Fortran source format
+def fortran_format_Group : OptionGroup<"Fortran format Group">, Group<gfortran_Group>;
// "f" flags for gfortran.
defm aggressive_function_elimination : BooleanFFlag<"aggressive-function-elimination">, Group<gfortran_Group>;
defm align_commons : BooleanFFlag<"align-commons">, Group<gfortran_Group>;
defm all_intrinsics : BooleanFFlag<"all-intrinsics">, Group<gfortran_Group>;
defm automatic : BooleanFFlag<"automatic">, Group<gfortran_Group>;
-defm backslash : BooleanFFlag<"backslash">, Group<gfortran_Group>;
+def fbackslash: Flag<["-"], "fbackslash">, Group<gfortran_Group>,
+ HelpText<"Treat backslash as C-style escape character">;
+def fnobackslash: Flag<["-"], "fno-backslash">, Group<gfortran_Group>,
+ HelpText<"Treat backslash like any other character in character strings">;
defm backtrace : BooleanFFlag<"backtrace">, Group<gfortran_Group>;
defm bounds_check : BooleanFFlag<"bounds-check">, Group<gfortran_Group>;
defm check_array_temporaries : BooleanFFlag<"check-array-temporaries">, Group<gfortran_Group>;
@@ -3356,17 +3370,27 @@ defm cray_pointer : BooleanFFlag<"cray-pointer">, Group<gfortran_Group>;
defm d_lines_as_code : BooleanFFlag<"d-lines-as-code">, Group<gfortran_Group>;
defm d_lines_as_comments : BooleanFFlag<"d-lines-as-comments">, Group<gfortran_Group>;
defm default_double_8 : BooleanFFlag<"default-double-8">, Group<gfortran_Group>;
-defm default_integer_8 : BooleanFFlag<"default-integer-8">, Group<gfortran_Group>;
-defm default_real_8 : BooleanFFlag<"default-real-8">, Group<gfortran_Group>;
+def default_integer_8_f : Flag<["-"], "fdefault-integer-8">, Group<gfortran_Group>,
+ HelpText<"Treat INTEGER and LOGICAL as INTEGER*8 and LOGICAL*8">;
+def default_integer_8_fno : Flag<["-"], "fno-default-integer-8">, Group<gfortran_Group>;
+def default_real_8_f : Flag<["-"], "fdefault-real-8">, Group<gfortran_Group>,
+ HelpText<"Treat REAL as REAL*8">;
+def default_real_8_fno : Flag<["-"], "fno-default-real-8">, Group<gfortran_Group>;
defm dollar_ok : BooleanFFlag<"dollar-ok">, Group<gfortran_Group>;
defm dump_fortran_optimized : BooleanFFlag<"dump-fortran-optimized">, Group<gfortran_Group>;
defm dump_fortran_original : BooleanFFlag<"dump-fortran-original">, Group<gfortran_Group>;
defm dump_parse_tree : BooleanFFlag<"dump-parse-tree">, Group<gfortran_Group>;
defm external_blas : BooleanFFlag<"external-blas">, Group<gfortran_Group>;
defm f2c : BooleanFFlag<"f2c">, Group<gfortran_Group>;
-defm fixed_form : BooleanFFlag<"fixed-form">, Group<gfortran_Group>;
-defm free_form : BooleanFFlag<"free-form">, Group<gfortran_Group>;
-defm frontend_optimize : BooleanFFlag<"frontend-optimize">, Group<gfortran_Group>;
+def fixed_form_on : Flag<["-"], "ffixed-form">, Group<fortran_format_Group>,
+ HelpText<"Enable fixed-form format for Fortran">;
+def fixed_form_off : Flag<["-"], "fno-fixed-form">, Group<fortran_format_Group>,
+ HelpText<"Disable fixed-form format for Fortran">;
+def free_form_on : Flag<["-"], "ffree-form">, Group<fortran_format_Group>,
+ HelpText<"Enable free-form format for Fortran">;
+def free_form_off : Flag<["-"], "fno-free-form">, Group<fortran_format_Group>,
+ HelpText<"Disable free-form format for Fortran">;
+defm frontend_optimize : BooleanFFlag<"frontend-optimize">, Group<fortran_format_Group>;
defm implicit_none : BooleanFFlag<"implicit-none">, Group<gfortran_Group>;
defm init_local_zero : BooleanFFlag<"init-local-zero">, Group<gfortran_Group>;
defm integer_4_integer_8 : BooleanFFlag<"integer-4-integer-8">, Group<gfortran_Group>;
@@ -3391,6 +3415,137 @@ defm stack_arrays : BooleanFFlag<"stack-arrays">, Group<gfortran_Group>;
defm underscoring : BooleanFFlag<"underscoring">, Group<gfortran_Group>;
defm whole_file : BooleanFFlag<"whole-file">, Group<gfortran_Group>;
+// Flang-specific options
+multiclass BooleanKFlag<string name> {
+ def _on : Flag<["-"], "K"#name>;
+ def _off : Flag<["-"], "Kno"#name>;
+}
+
+multiclass BooleanMFlag<string name> {
+ def _on : Flag<["-"], "M"#name>;
+ def _off : Flag<["-"], "Mno"#name>;
+}
+
+def Mfixed : Flag<["-"], "Mfixed">, Group<fortran_format_Group>,
+ HelpText<"Force fixed-form format Fortran">,
+ Flags<[HelpHidden]>;
+def Mfree_on: Flag<["-"], "Mfree">, Group<fortran_format_Group>,
+ HelpText<"Enable free-form format for Fortran">,
+ Flags<[HelpHidden]>;
+def Mfree_off: Flag<["-"], "Mnofree">, Group<fortran_format_Group>,
+ HelpText<"Disable free-form format for Fortran">,
+ Flags<[HelpHidden]>;
+def Mfreeform_on: Flag<["-"], "Mfreeform">, Group<fortran_format_Group>,
+ HelpText<"Enable free-form format for Fortran">,
+ Flags<[HelpHidden]>;
+def Mfreeform_off: Flag<["-"], "Mnofreeform">, Group<fortran_format_Group>,
+ HelpText<"Disable free-form format for Fortran">,
+ Flags<[HelpHidden]>;
+
+def Minfo_EQ : CommaJoined<["-"], "Minfo=">,
+ HelpText<"Diagnostic information about successful optimizations">,
+ Values<"all,vect,inline">;
+def Minfoall : Flag<["-"], "Minfo">,
+ HelpText<"Diagnostic information about all successful optimizations">;
+def Mneginfo_EQ : CommaJoined<["-"], "Mneginfo=">,
+ HelpText<"Diagnostic information about missed optimizations">,
+ Values<"all,vect,inline">;
+def Mneginfoall : Flag<["-"], "Mneginfo">,
+ HelpText<"Diagnostic information about all missed optimizations">;
+def Mipa: Joined<["-"], "Mipa">, Group<pgi_fortran_Group>;
+def Mstackarrays: Joined<["-"], "Mstack_arrays">, Group<pgi_fortran_Group>;
+def pc: JoinedOrSeparate<["-"], "pc">, Group<pgi_fortran_Group>;
+def Mfprelaxed: Joined<["-"], "Mfprelaxed">, Group<pgi_fortran_Group>;
+def Mnofprelaxed: Joined<["-"], "Mnofprelaxed">, Group<pgi_fortran_Group>;
+defm Mstride0: BooleanMFlag<"stride0">, Group<pgi_fortran_Group>;
+defm Mrecursive: BooleanMFlag<"recursive">, Group<pgi_fortran_Group>;
+defm Mreentrant: BooleanMFlag<"reentrant">, Group<pgi_fortran_Group>;
+defm Mbounds: BooleanMFlag<"bounds">, Group<pgi_fortran_Group>;
+def Mdaz_on: Flag<["-"], "Mdaz">, Group<pgi_fortran_Group>,
+ HelpText<"Treat denormalized numbers as zero">;
+def Mdaz_off: Flag<["-"], "Mnodaz">, Group<pgi_fortran_Group>,
+ HelpText<"Disable treating denormalized numbers as zero">;
+def Kieee_on : Flag<["-"], "Kieee">, Group<pgi_fortran_Group>,
+ HelpText<"Enable IEEE division">;
+def Kieee_off : Flag<["-"], "Knoieee">, Group<pgi_fortran_Group>,
+ HelpText<"Disable IEEE division">;
+def Mextend : Flag<["-"], "Mextend">, Group<pgi_fortran_Group>,
+ HelpText<"Allow lines up to 132 characters in Fortran sources">;
+def Mpreprocess : Flag<["-"], "Mpreprocess">, Group<pgi_fortran_Group>,
+ HelpText<"Preprocess Fortran files">;
+def Mstandard: Flag<["-"], "Mstandard">, Group<pgi_fortran_Group>,
+ HelpText<"Check Fortran standard conformance">;
+def Mchkptr: Flag<["-"], "Mchkptr">, Group<pgi_fortran_Group>;
+def Mwritable_constants: Flag<["-"], "Mwritable-constants">, Group<pgi_fortran_Group>,
+ HelpText<"Store constants in the writable data segment">;
+defm Minline: BooleanMFlag<"inline">, Group<pgi_fortran_Group>;
+def fma: Flag<["-"], "fma">, Group<pgi_fortran_Group>,
+ HelpText<"Enable generation of FMA instructions">;
+def nofma: Flag<["-"], "nofma">, Group<pgi_fortran_Group>,
+ HelpText<"Disable generation of FMA instructions">;
+defm Mfma: BooleanMFlag<"fma">, Group<pgi_fortran_Group>,
+ HelpText<"Enable generation of FMA instructions">;
+def mp: Flag<["-"], "mp">, Group<pgi_fortran_Group>,
+ HelpText<"Enable OpenMP">;
+def nomp: Flag<["-"], "nomp">, Group<pgi_fortran_Group>,
+ HelpText<"Do not link with OpenMP library libomp">;
+def Mflushz_on: Flag<["-"], "Mflushz">, Group<pgi_fortran_Group>,
+ HelpText<"Set SSE to flush-to-zero mode">;
+def Mflushz_off: Flag<["-"], "Mnoflushz">, Group<pgi_fortran_Group>,
+ HelpText<"Disabling setting SSE to flush-to-zero mode">;
+def Msave_on: Flag<["-"], "Msave">, Group<pgi_fortran_Group>,
+ HelpText<"Assume all Fortran variables have SAVE attribute">;
+def Msave_off: Flag<["-"], "Mnosave">, Group<pgi_fortran_Group>,
+ HelpText<"Assume no Fortran variables have SAVE attribute">;
+def Mcache_align_on: Flag<["-"], "Mcache_align">, Group<pgi_fortran_Group>,
+ HelpText<"Align large objects on cache-line boundaries">;
+def Mcache_align_off: Flag<["-"], "Mnocache_align">, Group<pgi_fortran_Group>,
+ HelpText<"Disable aligning large objects on cache-line boundaries">;
+def ModuleDir : Separate<["-"], "module">, Group<pgi_fortran_Group>,
+ HelpText<"Fortran module path">;
+def Minform_EQ : Joined<["-"], "Minform=">,
+ HelpText<"Set error level of messages to display">;
+def Mallocatable_EQ : Joined<["-"], "Mallocatable=">,
+ HelpText<"Select semantics for assignments to allocatables (F03 or F95)">;
+def Mbyteswapio: Flag<["-"], "Mbyteswapio">, Group<pgi_fortran_Group>,
+ HelpText<"Swap byte-order for unformatted input/output">;
+def byteswapio: Flag<["-"], "byteswapio">, Group<gfortran_Group>,
+ HelpText<"Swap byte-order for unformatted input/output">;
+def Mbackslash: Flag<["-"], "Mbackslash">, Group<pgi_fortran_Group>,
+ HelpText<"Treat backslash like any other character in character strings">;
+def Mnobackslash: Flag<["-"], "Mnobackslash">, Group<pgi_fortran_Group>,
+ HelpText<"Treat backslash as C-style escape character">;
+def staticFlangLibs: Flag<["-"], "static-flang-libs">, Group<flang_rt_Group>,
+ HelpText<"Link using static Flang libraries">;
+def noFlangLibs: Flag<["-"], "no-flang-libs">, Group<flang_rt_Group>,
+ HelpText<"Do not link against Flang libraries">;
+def r8: Flag<["-"], "r8">, Group<pgi_fortran_Group>,
+ HelpText<"Treat REAL as REAL*8">;
+def i8: Flag<["-"], "i8">, Group<pgi_fortran_Group>,
+ HelpText<"Treat INTEGER and LOGICAL as INTEGER*8 and LOGICAL*8">;
+def no_fortran_main: Flag<["-"], "fno-fortran-main">, Group<gfortran_Group>,
+ HelpText<"Don't link in Fortran main">;
+def Mnomain: Flag<["-"], "Mnomain">, Group<pgi_fortran_Group>,
+ HelpText<"Don't link in Fortran main">;
+def frelaxed_math : Flag<["-"], "frelaxed-math">, Group<pgi_fortran_Group>,
+ HelpText<"Use relaxed Math intrinsic functions">;
+def Memit_dwarf_common_blocks_name: Flag<["-"], "Memit-dwarf-common-blocks-name">,
+ Group<pgi_fortran_Group>, HelpText<"Emit COMMON blocks name in DWARF">;
+def Munixlogical: Flag<["-"], "Munixlogical">, Group<pgi_fortran_Group>,
+ HelpText<"Use unixlogical for all loigical operations">;
+
+// Flang internal debug options
+def Mx_EQ : Joined<["-"], "Mx,">, Group<pgi_fortran_Group>;
+def My_EQ : Joined<["-"], "My,">, Group<pgi_fortran_Group>;
+def Hx_EQ : Joined<["-"], "Hx,">, Group<pgi_fortran_Group>;
+def Hy_EQ : Joined<["-"], "Hy,">, Group<pgi_fortran_Group>;
+def Wm_EQ : Joined<["-"], "Wm,">, Group<pgi_fortran_Group>;
+
+def Mq_EQ : Joined<["-"], "Mq,">, Group<pgi_fortran_Group>;
+def Hq_EQ : Joined<["-"], "Hq,">, Group<pgi_fortran_Group>;
+def Mqq_EQ : Joined<["-"], "Mqq,">, Group<pgi_fortran_Group>;
+def Hqq_EQ : Joined<["-"], "Hqq,">, Group<pgi_fortran_Group>;
+def Wh_EQ : Joined<["-"], "Wh,">, Group<pgi_fortran_Group>;
include "CC1Options.td"
diff --git a/clang/include/clang/Driver/Phases.h b/clang/include/clang/Driver/Phases.h
index 63931c00c890..994d5608fb18 100644
--- a/clang/include/clang/Driver/Phases.h
+++ b/clang/include/clang/Driver/Phases.h
@@ -17,6 +17,7 @@ namespace phases {
enum ID {
Preprocess,
Precompile,
+ FortranFrontend,
Compile,
Backend,
Assemble,
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index 26d8d43dd2fc..c7800a3c43d4 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -135,6 +135,7 @@ class ToolChain {
mutable std::unique_ptr<Tool> Clang;
mutable std::unique_ptr<Tool> Flang;
+ mutable std::unique_ptr<Tool> FortranFrontend;
mutable std::unique_ptr<Tool> Assemble;
mutable std::unique_ptr<Tool> Link;
mutable std::unique_ptr<Tool> IfsMerge;
@@ -143,6 +144,7 @@ class ToolChain {
Tool *getClang() const;
Tool *getFlang() const;
+ Tool *getFortranFrontend() const;
Tool *getAssemble() const;
Tool *getLink() const;
Tool *getIfsMerge() const;
@@ -521,6 +523,14 @@ class ToolChain {
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const;
+ /// \brief Add the flang arguments for system include paths.
+ ///
+ /// This routine is responsible for adding the -stdinc argument to
+ /// include headers and module files from standard system header directories.
+ virtual void
+ AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &Flang1Args) const { }
+
/// Add options that need to be passed to cc1 for this target.
virtual void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args,
@@ -595,6 +605,11 @@ class ToolChain {
virtual VersionTuple computeMSVCVersion(const Driver *D,
const llvm::opt::ArgList &Args) const;
+ /// AddFortranStdlibLibArgs - Add the system specific linker arguments to use
+ /// for the given Fortran runtime library type.
+ virtual void AddFortranStdlibLibArgs(const llvm::opt::ArgList &Args,
+ llvm::opt::ArgStringList &CmdArgs) const;
+
/// Return sanitizers which are available in this toolchain.
virtual SanitizerMask getSupportedSanitizers() const;
diff --git a/clang/include/clang/Driver/Types.def b/clang/include/clang/Driver/Types.def
index 79e8d109cd97..382175dabcce 100644
--- a/clang/include/clang/Driver/Types.def
+++ b/clang/include/clang/Driver/Types.def
@@ -71,8 +71,15 @@ TYPE("c++-module-cpp-output", PP_CXXModule, INVALID, "iim", phases
TYPE("ada", Ada, INVALID, nullptr, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("assembler", PP_Asm, INVALID, "s", phases::Assemble, phases::Link)
TYPE("assembler-with-cpp", Asm, PP_Asm, "S", phases::Preprocess, phases::Assemble, phases::Link)
+#ifdef USE_CLASSIC_FLANG
+TYPE("f77", PP_F_FixedForm, INVALID, "f", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("f77-cpp-input", F_FixedForm, PP_F_FixedForm, "F", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("f95", PP_F_FreeForm, INVALID, "f95", phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("f95-cpp-input", F_FreeForm, PP_F_FreeForm, "F95", phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+#else
TYPE("f95", PP_Fortran, INVALID, nullptr, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
TYPE("f95-cpp-input", Fortran, PP_Fortran, nullptr, phases::Preprocess, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+#endif
TYPE("java", Java, INVALID, nullptr, phases::Compile, phases::Backend, phases::Assemble, phases::Link)
// LLVM IR/LTO types. We define separate types for IR and LTO because LTO
diff --git a/clang/include/clang/Driver/Types.h b/clang/include/clang/Driver/Types.h
index c7c38fa52593..80226792477c 100644
--- a/clang/include/clang/Driver/Types.h
+++ b/clang/include/clang/Driver/Types.h
@@ -87,6 +87,14 @@ namespace types {
/// isFortran - Is this a Fortran input.
bool isFortran(ID Id);
+#ifdef USE_CLASSIC_FLANG
+ /// isFreeFormFortran -- is it a free form layout Fortran input
+ bool isFreeFormFortran(ID Id);
+
+ /// isFixedFormFortran -- is it a fixed form layout Fortran input
+ bool isFixedFormFortran(ID Id);
+#endif
+
/// isSrcFile - Is this a source file, i.e. something that still has to be
/// preprocessed. The logic behind this is the same that decides if the first
/// compilation phase is a preprocessing one.
diff --git a/clang/include/clang/Frontend/Utils.h b/clang/include/clang/Frontend/Utils.h
index b5834921b9ed..680710b9118f 100644
--- a/clang/include/clang/Frontend/Utils.h
+++ b/clang/include/clang/Frontend/Utils.h
@@ -17,6 +17,7 @@
#include "clang/Basic/LLVM.h"
#include "clang/Driver/OptionUtils.h"
#include "clang/Frontend/DependencyOutputOptions.h"
+#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringMap.h"
@@ -34,6 +35,7 @@
namespace llvm {
class Triple;
+class StringRef;
} // namespace llvm
@@ -48,6 +50,7 @@ class FrontendOptions;
class HeaderSearch;
class HeaderSearchOptions;
class LangOptions;
+class MacroBuilder;
class PCHContainerReader;
class Preprocessor;
class PreprocessorOptions;
@@ -69,6 +72,29 @@ void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts,
void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS,
const PreprocessorOutputOptions &Opts);
+/// DefineTypeSize - Emit a macro to the predefines buffer that declares a macro
+/// named MacroName with the max value for a type with width 'TypeWidth' a
+/// signedness of 'isSigned' and with a value suffix of 'ValSuffix' (e.g. LL).
+template<typename T>
+static void DefineTypeSize(const Twine &MacroName, unsigned TypeWidth,
+ StringRef ValSuffix, bool isSigned,
+ T &Builder) {
+ static_assert(std::is_base_of<MacroBuilder, T>::value, "Illegal T value");
+ llvm::APInt MaxVal = isSigned ? llvm::APInt::getSignedMaxValue(TypeWidth)
+ : llvm::APInt::getMaxValue(TypeWidth);
+ Builder.defineMacro(MacroName, MaxVal.toString(10, isSigned) + ValSuffix);
+}
+
+/// DefineTypeSize - An overloaded helper that uses TargetInfo to determine
+/// the width, suffix, and signedness of the given type
+template<typename T>
+static void DefineTypeSize(const Twine &MacroName, TargetInfo::IntType Ty,
+ const TargetInfo &TI, T &Builder) {
+ static_assert(std::is_base_of<MacroBuilder, T>::value, "Illegal T value");
+ DefineTypeSize(MacroName, TI.getTypeWidth(Ty), TI.getTypeConstantSuffix(Ty),
+ TI.isTypeSigned(Ty), Builder);
+}
+
/// An interface for collecting the dependencies of a compilation. Users should
/// use \c attachToPreprocessor and \c attachToASTReader to get all of the
/// dependencies.
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 0bfcab88a3a9..59afa7aad484 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -354,6 +354,11 @@ static TargetLibraryInfoImpl *createTLII(llvm::Triple &TargetTriple,
case CodeGenOptions::SVML:
TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::SVML);
break;
+#ifdef FLANG_LLVM_EXTENSIONS
+ case CodeGenOptions::PGMATH:
+ TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::PGMATH);
+ break;
+#endif
default:
break;
}
diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp
index 20ebaf3578d6..594cc85e3510 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -1165,13 +1165,14 @@ void CodeGenAction::ExecuteAction() {
std::unique_ptr<llvm::ToolOutputFile> OptRecordFile =
std::move(*OptRecordFileOrErr);
- EmitBackendOutput(Diagnostics, CI.getHeaderSearchOpts(), CodeGenOpts,
- TargetOpts, CI.getLangOpts(),
+ EmitBackendOutput(CI.getDiagnostics(), CI.getHeaderSearchOpts(),
+ CI.getCodeGenOpts(), TargetOpts, CI.getLangOpts(),
CI.getTarget().getDataLayout(), TheModule.get(), BA,
std::move(OS));
if (OptRecordFile)
OptRecordFile->keep();
+
return;
}
diff --git a/clang/lib/Driver/Action.cpp b/clang/lib/Driver/Action.cpp
index 0eb4c7257e7a..a0a1d9953fe4 100644
--- a/clang/lib/Driver/Action.cpp
+++ b/clang/lib/Driver/Action.cpp
@@ -28,6 +28,7 @@ const char *Action::getClassName(ActionClass AC) {
case HeaderModulePrecompileJobClass: return "header-module-precompiler";
case AnalyzeJobClass: return "analyzer";
case MigrateJobClass: return "migrator";
+ case FortranFrontendJobClass: return "fortran-frontend";
case CompileJobClass: return "compiler";
case BackendJobClass: return "backend";
case AssembleJobClass: return "assembler";
@@ -345,6 +346,12 @@ void MigrateJobAction::anchor() {}
MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType)
: JobAction(MigrateJobClass, Input, OutputType) {}
+void FortranFrontendJobAction::anchor() {}
+
+FortranFrontendJobAction::FortranFrontendJobAction(Action *Input,
+ types::ID OutputType)
+ : JobAction(FortranFrontendJobClass, Input, OutputType) {}
+
void CompileJobAction::anchor() {}
CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType)
diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt
index 6f25d3588ebb..561939e6dc5c 100644
--- a/clang/lib/Driver/CMakeLists.txt
+++ b/clang/lib/Driver/CMakeLists.txt
@@ -46,6 +46,7 @@ add_clang_library(clangDriver
ToolChains/Darwin.cpp
ToolChains/DragonFly.cpp
ToolChains/Flang.cpp
+ ToolChains/Flang1.cpp
ToolChains/FreeBSD.cpp
ToolChains/Fuchsia.cpp
ToolChains/Gnu.cpp
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index fb8335a3695d..5b5053f3bb73 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -271,18 +271,42 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL,
// -{E,EP,P,M,MM} only run the preprocessor.
if (CCCIsCPP() || (PhaseArg = DAL.getLastArg(options::OPT_E)) ||
+#ifdef USE_CLASSIC_FLANG
+ (PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
+#endif
(PhaseArg = DAL.getLastArg(options::OPT__SLASH_EP)) ||
(PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM)) ||
(PhaseArg = DAL.getLastArg(options::OPT__SLASH_P))) {
+#ifdef USE_CLASSIC_FLANG
+ // -fsyntax-only or -E stops Fortran compilation after FortranFrontend
+ if (IsFlangMode() && (DAL.getLastArg(options::OPT_E) ||
+ DAL.getLastArg(options::OPT_fsyntax_only))) {
+ FinalPhase = phases::FortranFrontend;
+
+ // if not Fortran, fsyntax_only implies 'Compile' is the FinalPhase
+ } else if (DAL.getLastArg(options::OPT_fsyntax_only)) {
+ FinalPhase = phases::Compile;
+
+ // everything else has 'Preprocess' as its FinalPhase
+ } else {
+ FinalPhase = phases::Preprocess;
+ }
+#else
FinalPhase = phases::Preprocess;
+#endif
// --precompile only runs up to precompilation.
} else if ((PhaseArg = DAL.getLastArg(options::OPT__precompile))) {
FinalPhase = phases::Precompile;
+#ifdef USE_CLASSIC_FLANG
+ // -{analyze,emit-ast} only run up to the compiler.
+ } else if ((PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
+#else
// -{fsyntax-only,-analyze,emit-ast} only run up to the compiler.
} else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
(PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) ||
+#endif
(PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
(PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
(PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
@@ -3648,6 +3672,13 @@ Action *Driver::ConstructPhaseAction(
ModName);
return C.MakeAction<PrecompileJobAction>(Input, OutputTy);
}
+ case phases::FortranFrontend: {
+ if (Args.hasArg(options::OPT_fsyntax_only))
+ return C.MakeAction<FortranFrontendJobAction>(Input,
+ types::TY_Nothing);
+ return C.MakeAction<FortranFrontendJobAction>(Input,
+ types::TY_LLVM_IR);
+ }
case phases::Compile: {
if (Args.hasArg(options::OPT_fsyntax_only))
return C.MakeAction<CompileJobAction>(Input, types::TY_Nothing);
diff --git a/clang/lib/Driver/Phases.cpp b/clang/lib/Driver/Phases.cpp
index 01598c59bd9e..f0216c5ab7c2 100644
--- a/clang/lib/Driver/Phases.cpp
+++ b/clang/lib/Driver/Phases.cpp
@@ -16,6 +16,7 @@ const char *phases::getPhaseName(ID Id) {
switch (Id) {
case Preprocess: return "preprocessor";
case Precompile: return "precompiler";
+ case FortranFrontend: return "fortran-frontend";
case Compile: return "compiler";
case Backend: return "backend";
case Assemble: return "assembler";
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index cab97b1a601a..86e6e0c469a1 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -10,6 +10,7 @@
#include "InputInfo.h"
#include "ToolChains/Arch/ARM.h"
#include "ToolChains/Clang.h"
+#include "ToolChains/Flang1.h"
#include "ToolChains/InterfaceStubs.h"
#include "ToolChains/Flang.h"
#include "clang/Basic/ObjCRuntime.h"
@@ -276,6 +277,12 @@ Tool *ToolChain::getAssemble() const {
return Assemble.get();
}
+Tool *ToolChain::getFortranFrontend() const {
+ if (!FortranFrontend)
+ FortranFrontend.reset(new tools::FlangFrontend(*this));
+ return FortranFrontend.get();
+}
+
Tool *ToolChain::getClangAs() const {
if (!Assemble)
Assemble.reset(new tools::ClangAs(*this));
@@ -341,6 +348,9 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const {
case Action::OffloadWrapperJobClass:
return getOffloadWrapper();
+
+ case Action::FortranFrontendJobClass:
+ return getFortranFrontend();
}
llvm_unreachable("Invalid tool kind.");
@@ -551,13 +561,13 @@ std::string ToolChain::GetLinkerPath() const {
types::ID ToolChain::LookupTypeForExtension(StringRef Ext) const {
types::ID id = types::lookupTypeForExtension(Ext);
-
+#ifndef USE_CLASSIC_FLANG
// Flang always runs the preprocessor and has no notion of "preprocessed
// fortran". Here, TY_PP_Fortran is coerced to TY_Fortran to avoid treating
// them
diff erently.
if (D.IsFlangMode() && id == types::TY_PP_Fortran)
id = types::TY_Fortran;
-
+#endif
return id;
}
@@ -915,6 +925,49 @@ void ToolChain::AddCCKextLibArgs(const ArgList &Args,
CmdArgs.push_back("-lcc_kext");
}
+void ToolChain::AddFortranStdlibLibArgs(const ArgList &Args,
+ ArgStringList &CmdArgs) const {
+ bool staticFlangLibs = false;
+ bool useOpenMP = false;
+
+ if (Args.hasArg(options::OPT_staticFlangLibs)) {
+ for (auto *A: Args.filtered(options::OPT_staticFlangLibs)) {
+ A->claim();
+ staticFlangLibs = true;
+ }
+ }
+
+ Arg *A = Args.getLastArg(options::OPT_mp, options::OPT_nomp,
+ options::OPT_fopenmp, options::OPT_fno_openmp);
+ if (A &&
+ (A->getOption().matches(options::OPT_mp) ||
+ A->getOption().matches(options::OPT_fopenmp))) {
+ useOpenMP = true;
+ }
+
+ if (staticFlangLibs) {
+ CmdArgs.push_back("-Bstatic");
+ }
+ CmdArgs.push_back("-lflang");
+ CmdArgs.push_back("-lflangrti");
+ CmdArgs.push_back("-lpgmath");
+ if( useOpenMP ) {
+ CmdArgs.push_back("-lomp");
+ }
+ else {
+ CmdArgs.push_back("-lompstub");
+ }
+ if( staticFlangLibs ) {
+ CmdArgs.push_back("-Bdynamic");
+ }
+
+ CmdArgs.push_back("-lm");
+ CmdArgs.push_back("-lrt");
+
+ // Allways link Fortran executables with Pthreads
+ CmdArgs.push_back("-lpthread");
+}
+
bool ToolChain::AddFastMathRuntimeIfAvailable(const ArgList &Args,
ArgStringList &CmdArgs) const {
// Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index fa025be14e43..d004c1975926 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4370,7 +4370,68 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
else
CmdArgs.push_back(Args.MakeArgString(TC.getThreadModel()));
+#ifdef FLANG_LLVM_EXTENSIONS
+ if(Args.getLastArg(options::OPT_fveclib))
+ Args.AddLastArg(CmdArgs, options::OPT_fveclib);
+ else
+ CmdArgs.push_back("-fveclib=PGMATH");
+#else
Args.AddLastArg(CmdArgs, options::OPT_fveclib);
+#endif
+
+ std::string PassRemarkVal(""), PassRemarkOpt("");
+ if (Args.getLastArg(options::OPT_Minfoall)) {
+ PassRemarkVal = ".*";
+ Args.ClaimAllArgs(options::OPT_Minfoall);
+ } else if (Arg *A = Args.getLastArg(options::OPT_Minfo_EQ)) {
+ for (const StringRef &val : A->getValues()) {
+ if(val.equals("all")) {
+ PassRemarkVal = ".*";
+ break;
+ } else if(val.equals("inline") || val.equals("vect")) {
+ PassRemarkVal += PassRemarkVal.empty() ? "" : "|";
+ PassRemarkVal += val;
+ } else {
+ D.Diag(diag::err_drv_clang_unsupported_minfo_arg)
+ << A->getOption().getName()
+ << val.str();
+ break;
+ }
+ }
+ }
+ PassRemarkOpt = "-pass-remarks=" + PassRemarkVal;
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back(Args.MakeArgString(PassRemarkOpt));
+ Args.ClaimAllArgs(options::OPT_Minfo_EQ);
+ PassRemarkVal.clear();
+ PassRemarkOpt.clear();
+
+ if (Args.getLastArg(options::OPT_Mneginfoall)) {
+ PassRemarkVal = ".*";
+ Args.ClaimAllArgs(options::OPT_Mneginfoall);
+ } else if (Arg *A = Args.getLastArg(options::OPT_Mneginfo_EQ)) {
+ for (const StringRef &val : A->getValues()) {
+ if(val.equals("all")) {
+ PassRemarkVal = ".*";
+ break;
+ } else if(val.equals("inline") || val.equals("vect")) {
+ PassRemarkVal += PassRemarkVal.empty() ? "" : "|";
+ PassRemarkVal += val;
+ } else {
+ D.Diag(diag::err_drv_clang_unsupported_minfo_arg)
+ << A->getOption().getName()
+ << val.str();
+ break;
+ }
+ }
+ }
+ PassRemarkOpt = "-pass-remarks-missed=" + PassRemarkVal;
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back(Args.MakeArgString(PassRemarkOpt));
+ PassRemarkOpt = "-pass-remarks-analysis=" + PassRemarkVal;
+ CmdArgs.push_back("-mllvm");
+ CmdArgs.push_back(Args.MakeArgString(PassRemarkOpt));
+ Args.ClaimAllArgs(options::OPT_Mneginfo_EQ);
if (Args.hasFlag(options::OPT_fmerge_all_constants,
options::OPT_fno_merge_all_constants, false))
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 37ec73468570..e7cb13592d55 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -58,6 +58,23 @@ using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
+/// \brief Determine if Fortran link libraies are needed
+bool tools::needFortranLibs(const Driver &D, const ArgList &Args) {
+ if (D.IsFlangMode() && !Args.hasArg(options::OPT_nostdlib) &&
+ !Args.hasArg(options::OPT_noFlangLibs)) {
+ return true;
+ }
+
+ return false;
+}
+
+/// \brief Determine if Fortran "main" object is needed
+static bool needFortranMain(const Driver &D, const ArgList &Args) {
+ return (needFortranLibs(D, Args)
+ && (!Args.hasArg(options::OPT_Mnomain) ||
+ !Args.hasArg(options::OPT_no_fortran_main)));
+}
+
void tools::addPathIfExists(const Driver &D, const Twine &Path,
ToolChain::path_list &Paths) {
if (D.getVFS().exists(Path))
@@ -140,6 +157,7 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
const ArgList &Args, ArgStringList &CmdArgs,
const JobAction &JA) {
const Driver &D = TC.getDriver();
+ bool SeenFirstLinkerInput = false;
// Add extra linker input arguments which are not treated as inputs
// (constructed via -Xarch_).
@@ -171,6 +189,14 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
continue;
}
+ // Add Fortan "main" before the first linker input
+ if (!SeenFirstLinkerInput) {
+ if (needFortranMain(D, Args)) {
+ CmdArgs.push_back("-lflangmain");
+ }
+ SeenFirstLinkerInput = true;
+ }
+
// Otherwise, this is a linker input argument.
const Arg &A = II.getInputArg();
@@ -187,6 +213,15 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
A.renderAsInput(Args, CmdArgs);
}
}
+
+ if (!SeenFirstLinkerInput && needFortranMain(D, Args)) {
+ CmdArgs.push_back("-lflangmain");
+ }
+
+ // Claim "no Fortran main" arguments
+ for (auto Arg : Args.filtered(options::OPT_no_fortran_main, options::OPT_Mnomain)) {
+ Arg->claim();
+ }
}
void tools::AddTargetFeature(const ArgList &Args,
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h
index 84b9d2cf59b4..8e0d423970bf 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.h
+++ b/clang/lib/Driver/ToolChains/CommonArgs.h
@@ -20,6 +20,8 @@ namespace clang {
namespace driver {
namespace tools {
+bool needFortranLibs(const Driver &D, const llvm::opt::ArgList &Args);
+
void addPathIfExists(const Driver &D, const Twine &Path,
ToolChain::path_list &Paths);
diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp
index 50d22a2a8ea7..c0fc247bd343 100644
--- a/clang/lib/Driver/ToolChains/Cuda.cpp
+++ b/clang/lib/Driver/ToolChains/Cuda.cpp
@@ -877,3 +877,36 @@ VersionTuple CudaToolChain::computeMSVCVersion(const Driver *D,
const ArgList &Args) const {
return HostTC.computeMSVCVersion(D, Args);
}
+
+static void AddFlangSysIncludeArg(const ArgList &DriverArgs,
+ ArgStringList &Flang1Args,
+ ToolChain::path_list IncludePathList) {
+ std::string ArgValue; // Path argument value
+
+ // Make up argument value consisting of paths separated by colons
+ bool first = true;
+ for (auto P : IncludePathList) {
+ if (first) {
+ first = false;
+ } else {
+ ArgValue += ":";
+ }
+ ArgValue += P;
+ }
+
+ // Add the argument
+ Flang1Args.push_back("-stdinc");
+ Flang1Args.push_back(DriverArgs.MakeArgString(ArgValue));
+}
+
+void CudaToolChain::AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &Flang1Args) const {
+ path_list IncludePathList;
+ const Driver &D = getDriver();
+ if (DriverArgs.hasArg(options::OPT_nostdinc))
+ return;
+ SmallString<128> P(D.InstalledDir);
+ llvm::sys::path::append(P, "../include");
+ IncludePathList.push_back(P.str());
+ AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList);
+}
diff --git a/clang/lib/Driver/ToolChains/Cuda.h b/clang/lib/Driver/ToolChains/Cuda.h
index d1e066f93dfb..075f6eab36e8 100644
--- a/clang/lib/Driver/ToolChains/Cuda.h
+++ b/clang/lib/Driver/ToolChains/Cuda.h
@@ -193,6 +193,9 @@ class LLVM_LIBRARY_VISIBILITY CudaToolChain : public ToolChain {
const ToolChain &HostTC;
CudaInstallationDetector CudaInstallation;
+ void
+ AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &Flang1Args) const override;
protected:
Tool *buildAssembler() const override; // ptxas
Tool *buildLinker() const override; // fatbinary (ok, not really a linker)
diff --git a/clang/lib/Driver/ToolChains/Flang1.cpp b/clang/lib/Driver/ToolChains/Flang1.cpp
new file mode 100644
index 000000000000..17961d0bb499
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/Flang1.cpp
@@ -0,0 +1,1064 @@
+//===--- Flang.cpp - Flang+LLVM ToolChain Implementations -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Flang1.h"
+#include "CommonArgs.h"
+#include "InputInfo.h"
+#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/MacroBuilder.h"
+#include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TargetOptions.h"
+#include "clang/Basic/Version.h"
+#include "clang/Config/config.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
+#include "clang/Driver/SanitizerArgs.h"
+#include "clang/Driver/XRayArgs.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/Utils.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/Compression.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/TargetParser.h"
+#include "llvm/Support/YAMLParser.h"
+
+#ifdef LLVM_ON_UNIX
+#include <unistd.h> // For getuid().
+#endif
+
+using namespace clang::driver;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+class FlangMacroBuilder : public MacroBuilder {
+ ArgStringList &CmdArgs;
+ const ArgList &DriverArgs;
+ public:
+ FlangMacroBuilder(ArgStringList &UpperCmdArgs, const ArgList &DriverArgs, llvm::raw_string_ostream &Output)
+ : MacroBuilder(Output), CmdArgs(UpperCmdArgs), DriverArgs(DriverArgs) {
+ }
+ virtual void defineMacro(const Twine &Name, const Twine &Value = "1") {
+ CmdArgs.push_back("-def");
+ CmdArgs.push_back(DriverArgs.MakeArgString(Name + Twine('=') + Value));
+ }
+};
+
+void FlangFrontend::ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output, const InputInfoList &Inputs,
+ const ArgList &Args, const char *LinkingOutput) const {
+ ArgStringList CommonCmdArgs;
+ ArgStringList UpperCmdArgs;
+ ArgStringList LowerCmdArgs;
+ SmallString<256> Stem;
+ std::string OutFile;
+ bool NeedIEEE = false;
+ bool NeedFastMath = false;
+ bool NeedRelaxedMath = false;
+
+ // Check number of inputs for sanity. We need at least one input.
+ assert(Inputs.size() >= 1 && "Must have at least one input.");
+
+ /***** Process file arguments to both parts *****/
+ const InputInfo &Input = Inputs[0];
+ types::ID InputType = Input.getType();
+ // Check file type sanity
+ assert(types::isFortran(InputType) && "Can only accept Fortran");
+
+ if (Args.hasArg(options::OPT_fsyntax_only)) {
+ // For -fsyntax-only produce temp files only
+ Stem = C.getDriver().GetTemporaryPath("", "");
+ } else {
+ OutFile = Output.getFilename();
+ Stem = llvm::sys::path::filename(OutFile);
+ llvm::sys::path::replace_extension(Stem, "");
+ }
+
+ // Add input file name to the compilation line
+ UpperCmdArgs.push_back(Input.getBaseInput());
+
+ // Add temporary output for ILM
+ const char * ILMFile = Args.MakeArgString(Stem + ".ilm");
+ LowerCmdArgs.push_back(ILMFile);
+ C.addTempFile(ILMFile);
+
+ // Generate -cmdline
+ std::string CmdLine("'+flang");
+ // ignore the first argument which reads "--driver-mode=fortran"
+ for (unsigned i = 1; i < Args.getNumInputArgStrings(); ++i) {
+ CmdLine.append(" ");
+ CmdLine.append(Args.getArgString(i));
+ }
+ CmdLine.append("'");
+
+ CommonCmdArgs.push_back("-cmdline");
+ CommonCmdArgs.push_back(Args.MakeArgString(CmdLine));
+
+ /***** Process common args *****/
+
+ // Add "inform level" flag
+ if (Args.hasArg(options::OPT_Minform_EQ)) {
+ // Parse arguments to set its value
+ for (Arg *A : Args.filtered(options::OPT_Minform_EQ)) {
+ A->claim();
+ CommonCmdArgs.push_back("-inform");
+ CommonCmdArgs.push_back(A->getValue(0));
+ }
+ } else {
+ // Default value
+ CommonCmdArgs.push_back("-inform");
+ CommonCmdArgs.push_back("warn");
+ }
+
+ for (auto Arg : Args.filtered(options::OPT_Msave_on)) {
+ Arg->claim();
+ CommonCmdArgs.push_back("-save");
+ }
+
+ for (auto Arg : Args.filtered(options::OPT_Msave_off)) {
+ Arg->claim();
+ CommonCmdArgs.push_back("-nosave");
+ }
+
+ // Treat denormalized numbers as zero: On
+ for (auto Arg : Args.filtered(options::OPT_Mdaz_on)) {
+ Arg->claim();
+ CommonCmdArgs.push_back("-x");
+ CommonCmdArgs.push_back("129");
+ CommonCmdArgs.push_back("4");
+ CommonCmdArgs.push_back("-y");
+ CommonCmdArgs.push_back("129");
+ CommonCmdArgs.push_back("0x400");
+ }
+
+ // Treat denormalized numbers as zero: Off
+ for (auto Arg : Args.filtered(options::OPT_Mdaz_off)) {
+ Arg->claim();
+ CommonCmdArgs.push_back("-y");
+ CommonCmdArgs.push_back("129");
+ CommonCmdArgs.push_back("4");
+ CommonCmdArgs.push_back("-x");
+ CommonCmdArgs.push_back("129");
+ CommonCmdArgs.push_back("0x400");
+ }
+
+ // Store constants in writable data segment
+ for (auto Arg : Args.filtered(options::OPT_Mwritable_constants)) {
+ Arg->claim();
+ LowerCmdArgs.push_back("-x");
+ LowerCmdArgs.push_back("183");
+ LowerCmdArgs.push_back("0x20000000");
+ }
+
+ // Bounds checking: On
+ for (auto Arg : Args.filtered(options::OPT_Mbounds_on)) {
+ Arg->claim();
+ CommonCmdArgs.push_back("-x");
+ CommonCmdArgs.push_back("70");
+ CommonCmdArgs.push_back("2");
+ }
+
+ // Bounds checking: Off
+ for (auto Arg : Args.filtered(options::OPT_Mbounds_off)) {
+ Arg->claim();
+ CommonCmdArgs.push_back("-y");
+ CommonCmdArgs.push_back("70");
+ CommonCmdArgs.push_back("2");
+ }
+
+ // Generate code allowing recursive subprograms
+ for (auto Arg : Args.filtered(options::OPT_Mrecursive_on)) {
+ Arg->claim();
+ CommonCmdArgs.push_back("-recursive");
+ }
+
+ // Disable recursive subprograms
+ for (auto Arg : Args.filtered(options::OPT_Mrecursive_off)) {
+ Arg->claim();
+ CommonCmdArgs.push_back("-norecursive");
+ }
+
+ // Enable generating reentrant code (disable optimizations that inhibit it)
+ for (auto Arg : Args.filtered(options::OPT_Mreentrant_on)) {
+ Arg->claim();
+ CommonCmdArgs.push_back("-reentrant");
+ }
+
+ // Allow optimizations inhibiting reentrancy
+ for (auto Arg : Args.filtered(options::OPT_Mreentrant_off)) {
+ Arg->claim();
+ CommonCmdArgs.push_back("-noreentrant");
+ }
+
+ // Swap byte order for unformatted IO
+ for (auto Arg : Args.filtered(options::OPT_Mbyteswapio, options::OPT_byteswapio)) {
+ Arg->claim();
+ CommonCmdArgs.push_back("-x");
+ CommonCmdArgs.push_back("125");
+ CommonCmdArgs.push_back("2");
+ }
+
+ // Contiguous pointer checks
+ if (Arg *A = Args.getLastArg(options::OPT_fsanitize_EQ)) {
+ for (const StringRef &val : A->getValues()) {
+ if (val.equals("discontiguous") || val.equals("undefined") ) {
+ // -x 54 0x40 -x 54 0x80 -x 54 0x200
+ UpperCmdArgs.push_back("-x");
+ UpperCmdArgs.push_back("54");
+ UpperCmdArgs.push_back("0x2c0");
+
+ // -fsanitze=discontiguous has no meaning in LLVM, only flang driver needs to
+ // recognize it. However -fsanitize=undefined needs to be passed on for further
+ // processing by the non-flang part of the driver.
+ if (val.equals("discontiguous"))
+ A->claim();
+ break;
+ }
+ }
+ }
+
+ // Treat backslashes as regular characters
+ for (auto Arg : Args.filtered(options::OPT_fnobackslash, options::OPT_Mbackslash)) {
+ Arg->claim();
+ CommonCmdArgs.push_back("-x");
+ CommonCmdArgs.push_back("124");
+ CommonCmdArgs.push_back("0x40");
+ }
+
+ // Treat backslashes as C-style escape characters
+ for (auto Arg : Args.filtered(options::OPT_fbackslash, options::OPT_Mnobackslash)) {
+ Arg->claim();
+ CommonCmdArgs.push_back("-y");
+ CommonCmdArgs.push_back("124");
+ CommonCmdArgs.push_back("0x40");
+ }
+
+ // handle OpemMP options
+ if (auto *A = Args.getLastArg(options::OPT_mp, options::OPT_nomp,
+ options::OPT_fopenmp, options::OPT_fno_openmp)) {
+ for (auto Arg : Args.filtered(options::OPT_mp, options::OPT_nomp)) {
+ Arg->claim();
+ }
+ for (auto Arg : Args.filtered(options::OPT_fopenmp,
+ options::OPT_fno_openmp)) {
+ Arg->claim();
+ }
+
+ if (A->getOption().matches(options::OPT_mp) ||
+ A->getOption().matches(options::OPT_fopenmp)) {
+
+ CommonCmdArgs.push_back("-mp");
+
+ // Allocate threadprivate data local to the thread
+ CommonCmdArgs.push_back("-x");
+ CommonCmdArgs.push_back("69");
+ CommonCmdArgs.push_back("0x200");
+
+ // Use the 'fair' schedule as the default static schedule
+ // for parallel do loops
+ CommonCmdArgs.push_back("-x");
+ CommonCmdArgs.push_back("69");
+ CommonCmdArgs.push_back("0x400");
+
+ // Disable use of native atomic instructions
+ // for OpenMP atomics pending either a named
+ // option or a libatomic bundled with flang.
+ UpperCmdArgs.push_back("-x");
+ UpperCmdArgs.push_back("69");
+ UpperCmdArgs.push_back("0x1000");
+ }
+ }
+
+ // Align large objects on cache lines
+ for (auto Arg : Args.filtered(options::OPT_Mcache_align_on)) {
+ Arg->claim();
+ CommonCmdArgs.push_back("-x");
+ CommonCmdArgs.push_back("119");
+ CommonCmdArgs.push_back("0x10000000");
+ LowerCmdArgs.push_back("-x");
+ LowerCmdArgs.push_back("129");
+ LowerCmdArgs.push_back("0x40000000");
+ }
+
+ // Disable special alignment of large objects
+ for (auto Arg : Args.filtered(options::OPT_Mcache_align_off)) {
+ Arg->claim();
+ CommonCmdArgs.push_back("-y");
+ CommonCmdArgs.push_back("119");
+ CommonCmdArgs.push_back("0x10000000");
+ LowerCmdArgs.push_back("-y");
+ LowerCmdArgs.push_back("129");
+ LowerCmdArgs.push_back("0x40000000");
+ }
+
+ // -Mstack_arrays
+ for (auto Arg : Args.filtered(options::OPT_Mstackarrays)) {
+ Arg->claim();
+ CommonCmdArgs.push_back("-x");
+ CommonCmdArgs.push_back("54");
+ CommonCmdArgs.push_back("8");
+ }
+
+ // -Memit-dwarf-common-blocks-name, only add xbit to flang2.
+ for (auto Arg : Args.filtered(options::OPT_Memit_dwarf_common_blocks_name)) {
+ Arg->claim();
+ LowerCmdArgs.push_back("-x");
+ LowerCmdArgs.push_back("183");
+ LowerCmdArgs.push_back("0x40000000");
+ }
+
+ // -Munixlogical, only add xbit to flang2.
+ for (auto Arg : Args.filtered(options::OPT_Munixlogical)) {
+ Arg->claim();
+ LowerCmdArgs.push_back("-x");
+ LowerCmdArgs.push_back("125");
+ LowerCmdArgs.push_back("0x8");
+ }
+
+ // -g should produce DWARFv2
+ for (auto Arg : Args.filtered(options::OPT_g_Flag)) {
+ Arg->claim();
+ CommonCmdArgs.push_back("-x");
+ CommonCmdArgs.push_back("120");
+ CommonCmdArgs.push_back("0x200");
+ }
+
+ // -gdwarf-2
+ for (auto Arg : Args.filtered(options::OPT_gdwarf_2)) {
+ Arg->claim();
+ CommonCmdArgs.push_back("-x");
+ CommonCmdArgs.push_back("120");
+ CommonCmdArgs.push_back("0x200");
+ }
+
+ // -gdwarf-3
+ for (auto Arg : Args.filtered(options::OPT_gdwarf_3)) {
+ Arg->claim();
+ CommonCmdArgs.push_back("-x");
+ CommonCmdArgs.push_back("120");
+ CommonCmdArgs.push_back("0x4000");
+ }
+
+ // -Mipa has no effect
+ if (Arg *A = Args.getLastArg(options::OPT_Mipa)) {
+ getToolChain().getDriver().Diag(diag::warn_drv_clang_unsupported)
+ << A->getAsString(Args);
+ }
+
+ // -Minline has no effect
+ if (Arg *A = Args.getLastArg(options::OPT_Minline_on)) {
+ getToolChain().getDriver().Diag(diag::warn_drv_clang_unsupported)
+ << A->getAsString(Args);
+ }
+
+ // Handle -fdefault-real-8 (and its alias, -r8) and -fno-default-real-8
+ if (Arg *A = Args.getLastArg(options::OPT_r8,
+ options::OPT_default_real_8_f,
+ options::OPT_default_real_8_fno)) {
+ const char * fl;
+ // For -f version add -x flag, for -fno add -y
+ if (A->getOption().matches(options::OPT_default_real_8_fno)) {
+ fl = "-y";
+ } else {
+ fl = "-x";
+ }
+
+ for (Arg *A : Args.filtered(options::OPT_r8,
+ options::OPT_default_real_8_f,
+ options::OPT_default_real_8_fno)) {
+ A->claim();
+ }
+
+ UpperCmdArgs.push_back(fl);
+ UpperCmdArgs.push_back("124");
+ UpperCmdArgs.push_back("0x8");
+ UpperCmdArgs.push_back(fl);
+ UpperCmdArgs.push_back("124");
+ UpperCmdArgs.push_back("0x80000");
+ }
+
+ // Process and claim -i8/-fdefault-integer-8/-fno-default-integer-8 argument
+ if (Arg *A = Args.getLastArg(options::OPT_i8,
+ options::OPT_default_integer_8_f,
+ options::OPT_default_integer_8_fno)) {
+ const char * fl;
+
+ if (A->getOption().matches(options::OPT_default_integer_8_fno)) {
+ fl = "-y";
+ } else {
+ fl = "-x";
+ }
+
+ for (Arg *A : Args.filtered(options::OPT_i8,
+ options::OPT_default_integer_8_f,
+ options::OPT_default_integer_8_fno)) {
+ A->claim();
+ }
+
+ UpperCmdArgs.push_back(fl);
+ UpperCmdArgs.push_back("124");
+ UpperCmdArgs.push_back("0x10");
+ }
+
+ // Pass an arbitrary flag for first part of Fortran frontend
+ for (Arg *A : Args.filtered(options::OPT_Wh_EQ)) {
+ A->claim();
+ StringRef Value = A->getValue();
+ SmallVector<StringRef, 8> PassArgs;
+ Value.split(PassArgs, StringRef(","));
+ for (StringRef PassArg : PassArgs) {
+ UpperCmdArgs.push_back(Args.MakeArgString(PassArg));
+ }
+ }
+
+ // Flush to zero mode
+ // Disabled by default, but can be enabled by a switch
+ if (Args.hasArg(options::OPT_Mflushz_on)) {
+ // For -Mflushz set -x 129 2 for second part of Fortran frontend
+ for (Arg *A: Args.filtered(options::OPT_Mflushz_on)) {
+ A->claim();
+ LowerCmdArgs.push_back("-x");
+ LowerCmdArgs.push_back("129");
+ LowerCmdArgs.push_back("2");
+ }
+ } else {
+ LowerCmdArgs.push_back("-y");
+ LowerCmdArgs.push_back("129");
+ LowerCmdArgs.push_back("2");
+ for (Arg *A: Args.filtered(options::OPT_Mflushz_off)) {
+ A->claim();
+ }
+ }
+
+ // Enable FMA
+ for (Arg *A: Args.filtered(options::OPT_Mfma_on, options::OPT_fma)) {
+ A->claim();
+ LowerCmdArgs.push_back("-x");
+ LowerCmdArgs.push_back("172");
+ LowerCmdArgs.push_back("0x40000000");
+ LowerCmdArgs.push_back("-x");
+ LowerCmdArgs.push_back("179");
+ LowerCmdArgs.push_back("1");
+ }
+
+ // Disable FMA
+ for (Arg *A: Args.filtered(options::OPT_Mfma_off, options::OPT_nofma)) {
+ A->claim();
+ LowerCmdArgs.push_back("-x");
+ LowerCmdArgs.push_back("171");
+ LowerCmdArgs.push_back("0x40000000");
+ LowerCmdArgs.push_back("-x");
+ LowerCmdArgs.push_back("178");
+ LowerCmdArgs.push_back("1");
+ }
+
+ // For -fPIC set -x 62 8 for second part of Fortran frontend
+ for (Arg *A: Args.filtered(options::OPT_fPIC)) {
+ A->claim();
+ LowerCmdArgs.push_back("-x");
+ LowerCmdArgs.push_back("62");
+ LowerCmdArgs.push_back("8");
+ }
+
+ StringRef OptOStr("0");
+ if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
+ if (A->getOption().matches(options::OPT_O4)) {
+ OptOStr = "4"; // FIXME what should this be?
+ } else if (A->getOption().matches(options::OPT_Ofast)) {
+ OptOStr = "2"; // FIXME what should this be?
+ } else if (A->getOption().matches(options::OPT_O0)) {
+ // intentionally do nothing
+ } else {
+ assert(A->getOption().matches(options::OPT_O) && "Must have a -O flag");
+ StringRef S(A->getValue());
+ if ((S == "s") || (S == "z")) {
+ // -Os = size; -Oz = more size
+ OptOStr = "2"; // FIXME -Os|-Oz => -opt ?
+ } else if ((S == "1") || (S == "2") || (S == "3")) {
+ OptOStr = S;
+ } else {
+ OptOStr = "4";
+ }
+ }
+ }
+ unsigned OptLevel = std::stoi(OptOStr.str());
+
+ if (Args.hasArg(options::OPT_g_Group)) {
+ // pass -g to lower and upper
+ CommonCmdArgs.push_back("-debug");
+ }
+
+ /* Pick the last among conflicting flags, if a positive and negative flag
+ exists for ex. "-ffast-math -fno-fast-math" they get nullified. Also any
+ previously overwritten flag remains that way.
+ For ex. "-Kieee -ffast-math -fno-fast-math". -Kieee gets overwritten by
+ -ffast-math which then gets negated by -fno-fast-math, finally behaving as
+ if none of those flags were passed.
+ */
+ for(Arg *A: Args.filtered(options::OPT_ffast_math, options::OPT_fno_fast_math,
+ options::OPT_Ofast, options::OPT_Kieee_off,
+ options::OPT_Kieee_on, options::OPT_frelaxed_math)) {
+ if (A->getOption().matches(options::OPT_ffast_math) ||
+ A->getOption().matches(options::OPT_Ofast)) {
+ NeedIEEE = NeedRelaxedMath = false;
+ NeedFastMath = true;
+ } else if (A->getOption().matches(options::OPT_Kieee_on)) {
+ NeedFastMath = NeedRelaxedMath = false;
+ NeedIEEE = true;
+ } else if (A->getOption().matches(options::OPT_frelaxed_math)) {
+ NeedFastMath = NeedIEEE = false;
+ NeedRelaxedMath = true;
+ } else if (A->getOption().matches(options::OPT_fno_fast_math)) {
+ NeedFastMath = false;
+ } else if (A->getOption().matches(options::OPT_Kieee_off)) {
+ NeedIEEE = false;
+ }
+ A->claim();
+ }
+
+ if (NeedFastMath) {
+ // Lower: -x 216 1
+ LowerCmdArgs.push_back("-x");
+ LowerCmdArgs.push_back("216");
+ LowerCmdArgs.push_back("1");
+ // Lower: -ieee 0
+ CommonCmdArgs.push_back("-ieee");
+ CommonCmdArgs.push_back("0");
+ } else if (NeedIEEE) {
+ // Common: -y 129 2
+ CommonCmdArgs.push_back("-y");
+ CommonCmdArgs.push_back("129");
+ CommonCmdArgs.push_back("2");
+ // Lower: -x 6 0x100
+ LowerCmdArgs.push_back("-x");
+ LowerCmdArgs.push_back("6");
+ LowerCmdArgs.push_back("0x100");
+ // Lower: -x 42 0x400000
+ LowerCmdArgs.push_back("-x");
+ LowerCmdArgs.push_back("42");
+ LowerCmdArgs.push_back("0x400000");
+ // Lower: -y 129 4
+ LowerCmdArgs.push_back("-y");
+ LowerCmdArgs.push_back("129");
+ LowerCmdArgs.push_back("4");
+ // Lower: -x 129 0x400
+ LowerCmdArgs.push_back("-x");
+ LowerCmdArgs.push_back("129");
+ LowerCmdArgs.push_back("0x400");
+ // Lower: -y 216 1 (OPT_fno_fast_math)
+ LowerCmdArgs.push_back("-y");
+ LowerCmdArgs.push_back("216");
+ LowerCmdArgs.push_back("1");
+ // Lower: -ieee 1
+ CommonCmdArgs.push_back("-ieee");
+ CommonCmdArgs.push_back("1");
+ } else if (NeedRelaxedMath) {
+ // Lower: -x 15 0x400
+ LowerCmdArgs.push_back("-x");
+ LowerCmdArgs.push_back("15");
+ LowerCmdArgs.push_back("0x400");
+ // Lower: -y 216 1 (OPT_fno_fast_math)
+ LowerCmdArgs.push_back("-y");
+ LowerCmdArgs.push_back("216");
+ LowerCmdArgs.push_back("1");
+ // Lower: -ieee 0
+ CommonCmdArgs.push_back("-ieee");
+ CommonCmdArgs.push_back("0");
+ } else {
+ // Lower: -ieee 0
+ CommonCmdArgs.push_back("-ieee");
+ CommonCmdArgs.push_back("0");
+ }
+
+ /***** Upper part of the Fortran frontend *****/
+
+ // TODO do we need to invoke this under GDB sometimes?
+ const char *UpperExec = Args.MakeArgString(getToolChain().GetProgramPath("flang1"));
+
+ UpperCmdArgs.push_back("-opt"); UpperCmdArgs.push_back(Args.MakeArgString(OptOStr));
+ UpperCmdArgs.push_back("-terse"); UpperCmdArgs.push_back("1");
+ UpperCmdArgs.push_back("-inform"); UpperCmdArgs.push_back("warn");
+ UpperCmdArgs.push_back("-nohpf");
+ UpperCmdArgs.push_back("-nostatic");
+ UpperCmdArgs.append(CommonCmdArgs.begin(), CommonCmdArgs.end()); // Append common arguments
+ UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("19"); UpperCmdArgs.push_back("0x400000");
+ UpperCmdArgs.push_back("-quad");
+ UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("68"); UpperCmdArgs.push_back("0x1");
+ UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("59"); UpperCmdArgs.push_back("4");
+ UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("15"); UpperCmdArgs.push_back("2");
+ UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("49"); UpperCmdArgs.push_back("0x400004");
+ UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("51"); UpperCmdArgs.push_back("0x20");
+ UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("57"); UpperCmdArgs.push_back("0x4c");
+ UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("58"); UpperCmdArgs.push_back("0x10000");
+ UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("124"); UpperCmdArgs.push_back("0x1000");
+ UpperCmdArgs.push_back("-tp"); UpperCmdArgs.push_back("px");
+ UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("57"); UpperCmdArgs.push_back("0xfb0000");
+ UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("58"); UpperCmdArgs.push_back("0x78031040");
+ UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("47"); UpperCmdArgs.push_back("0x08");
+ UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("48"); UpperCmdArgs.push_back("4608");
+ UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("49"); UpperCmdArgs.push_back("0x100");
+ if (OptLevel >= 2) {
+ UpperCmdArgs.push_back("-x");
+ UpperCmdArgs.push_back("70");
+ UpperCmdArgs.push_back("0x6c00");
+ UpperCmdArgs.push_back("-x");
+ UpperCmdArgs.push_back("119");
+ UpperCmdArgs.push_back("0x10000000");
+ UpperCmdArgs.push_back("-x");
+ UpperCmdArgs.push_back("129");
+ UpperCmdArgs.push_back("2");
+ UpperCmdArgs.push_back("-x");
+ UpperCmdArgs.push_back("47");
+ UpperCmdArgs.push_back("0x400000");
+ UpperCmdArgs.push_back("-x");
+ UpperCmdArgs.push_back("52");
+ UpperCmdArgs.push_back("2");
+ }
+
+ // Add system include arguments.
+ getToolChain().AddFlangSystemIncludeArgs(Args, UpperCmdArgs);
+
+ // Use clang's predefined macros
+ DiagnosticsEngine DE(new DiagnosticIDs(), new DiagnosticOptions, new IgnoringDiagConsumer());
+ std::shared_ptr<clang::TargetOptions> TO = std::make_shared<clang::TargetOptions>();
+ TO->Triple = getToolChain().getEffectiveTriple().getTriple();
+ std::shared_ptr<TargetInfo> TI(clang::TargetInfo::CreateTargetInfo(DE, TO));
+ std::string PredefineBuffer;
+ llvm::raw_string_ostream Predefines(PredefineBuffer);
+ FlangMacroBuilder Builder(UpperCmdArgs, Args, Predefines);
+
+ LangOptions LO;
+ VersionTuple VT = getToolChain().computeMSVCVersion(&getToolChain().getDriver(), Args);
+ if (!VT.empty()) {
+ // Set the MSCompatibility version. Subminor version has 5 decimal digits.
+ // Minor and major versions have 2 decimal digits each.
+ LO.MSCompatibilityVersion = VT.getMajor() * 10000000 +
+ VT.getMinor().getValueOr(0) * 100000 +
+ VT.getSubminor().getValueOr(0);
+ }
+
+ // Define Target specific macros like __linux__
+ TI->getTargetDefines(LO, Builder);
+
+ Builder.defineMacro("__SIZE_TYPE__", TargetInfo::getTypeName(TI->getSizeType()));
+ Builder.defineMacro("__PTRDIFF_TYPE__", TargetInfo::getTypeName(TI->getPtrDiffType(0)));
+
+ if (TI->getPointerWidth(0) == 64 && TI->getLongWidth() == 64
+ && TI->getIntWidth() == 32) {
+ Builder.defineMacro("_LP64");
+ Builder.defineMacro("__LP64__");
+ }
+
+ if (TI->getPointerWidth(0) == 32 && TI->getLongWidth() == 32
+ && TI->getIntWidth() == 32) {
+ Builder.defineMacro("_ILP32");
+ Builder.defineMacro("__ILP32__");
+ }
+
+ DefineTypeSize("__LONG_MAX__", TargetInfo::SignedLong, *TI, Builder);
+
+ // Add additional predefined macros
+ switch (getToolChain().getEffectiveTriple().getArch()) {
+ case llvm::Triple::aarch64:
+ UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__ARM_ARCH__=8");
+ break;
+ case llvm::Triple::x86_64:
+ UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__amd_64__amd64__");
+ UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__k8");
+ UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__k8__");
+ break;
+ default: /* generic 64-bit */
+ ;
+ }
+ UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__THROW=");
+ UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__extension__=");
+ UpperCmdArgs.push_back("-def"); UpperCmdArgs.push_back("__PGLLVM__");
+
+ // Enable preprocessor
+ if (Args.hasArg(options::OPT_Mpreprocess) ||
+ Args.hasArg(options::OPT_cpp) ||
+ Args.hasArg(options::OPT_E) ||
+ types::getPreprocessedType(InputType) != types::TY_INVALID) {
+ UpperCmdArgs.push_back("-preprocess");
+ for (auto Arg : Args.filtered(options::OPT_Mpreprocess, options::OPT_cpp, options::OPT_E)) {
+ Arg->claim();
+ }
+
+ // When -E option is provided, run only the fortran preprocessor.
+ // Only in -E mode, consume -P if it exists
+ if (Args.hasArg(options::OPT_E)) {
+ UpperCmdArgs.push_back("-es");
+ // Line marker mode is disabled
+ if (Args.hasArg(options::OPT_P)) {
+ Args.ClaimAllArgs(options::OPT_P);
+ } else {
+ // -pp enables line marker mode in fortran preprocessor
+ UpperCmdArgs.push_back("-pp");
+ }
+ }
+ }
+
+ // Enable standards checking
+ if (Args.hasArg(options::OPT_Mstandard)) {
+ UpperCmdArgs.push_back("-standard");
+ for (auto Arg : Args.filtered(options::OPT_Mstandard)) {
+ Arg->claim();
+ }
+ }
+
+ // Free or fixed form file
+ if (Args.hasArg(options::OPT_fortran_format_Group)) {
+ // Override file name suffix, scan arguments for that
+ for (Arg *A : Args.filtered(options::OPT_fortran_format_Group)) {
+ A->claim();
+ switch (A->getOption().getID()) {
+ default:
+ llvm_unreachable("missed a case");
+ case options::OPT_fixed_form_on:
+ case options::OPT_free_form_off:
+ case options::OPT_Mfixed:
+ case options::OPT_Mfree_off:
+ case options::OPT_Mfreeform_off:
+ UpperCmdArgs.push_back("-nofreeform");
+ break;
+ case options::OPT_free_form_on:
+ case options::OPT_fixed_form_off:
+ case options::OPT_Mfree_on:
+ case options::OPT_Mfreeform_on:
+ UpperCmdArgs.push_back("-freeform");
+ break;
+ }
+ }
+ } else {
+ // Deduce format from file name suffix
+ if (types::isFreeFormFortran(InputType)) {
+ UpperCmdArgs.push_back("-freeform");
+ } else {
+ UpperCmdArgs.push_back("-nofreeform");
+ }
+ }
+
+ // Extend lines to 132 characters
+ for (auto Arg : Args.filtered(options::OPT_Mextend)) {
+ Arg->claim();
+ UpperCmdArgs.push_back("-extend");
+ }
+
+ for (auto Arg : Args.filtered(options::OPT_ffixed_line_length_VALUE)) {
+ StringRef Value = Arg->getValue();
+ if (Value == "72") {
+ Arg->claim();
+ } else if (Value == "132") {
+ Arg->claim();
+ UpperCmdArgs.push_back("-extend");
+ } else {
+ getToolChain().getDriver().Diag(diag::err_drv_unsupported_fixed_line_length)
+ << Arg->getAsString(Args);
+ }
+ }
+
+ // Add user-defined include directories
+ for (auto Arg : Args.filtered(options::OPT_I)) {
+ Arg->claim();
+ UpperCmdArgs.push_back("-idir");
+ UpperCmdArgs.push_back(Arg->getValue(0));
+ }
+
+ // Add user-defined module directories
+ for (auto Arg : Args.filtered(options::OPT_ModuleDir, options::OPT_J)) {
+ Arg->claim();
+ UpperCmdArgs.push_back("-moddir");
+ UpperCmdArgs.push_back(Arg->getValue(0));
+ }
+
+ // "Define" preprocessor flags
+ for (auto Arg : Args.filtered(options::OPT_D)) {
+ Arg->claim();
+ UpperCmdArgs.push_back("-def");
+ UpperCmdArgs.push_back(Arg->getValue(0));
+ }
+
+ // "Define" preprocessor flags
+ for (auto Arg : Args.filtered(options::OPT_U)) {
+ Arg->claim();
+ UpperCmdArgs.push_back("-undef");
+ UpperCmdArgs.push_back(Arg->getValue(0));
+ }
+
+ UpperCmdArgs.push_back("-vect"); UpperCmdArgs.push_back("48");
+
+ // Semantics for assignments to allocatables
+ if (Arg *A = Args.getLastArg(options::OPT_Mallocatable_EQ)) {
+ // Argument is passed explicitly
+ StringRef Value = A->getValue();
+ if (Value == "03") { // Enable Fortran 2003 semantics
+ UpperCmdArgs.push_back("-x"); // Set XBIT
+ } else if (Value == "95") { // Enable Fortran 2003 semantics
+ UpperCmdArgs.push_back("-y"); // Unset XBIT
+ } else {
+ getToolChain().getDriver().Diag(diag::err_drv_invalid_allocatable_mode)
+ << A->getAsString(Args);
+ }
+ } else { // No argument passed
+ UpperCmdArgs.push_back("-x"); // Default is 03
+ }
+ UpperCmdArgs.push_back("54"); UpperCmdArgs.push_back("1"); // XBIT value
+
+ UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("70"); UpperCmdArgs.push_back("0x40000000");
+ UpperCmdArgs.push_back("-y"); UpperCmdArgs.push_back("163"); UpperCmdArgs.push_back("0xc0000000");
+ UpperCmdArgs.push_back("-x"); UpperCmdArgs.push_back("189"); UpperCmdArgs.push_back("0x10");
+
+ // Enable NULL pointer checking
+ if (Args.hasArg(options::OPT_Mchkptr)) {
+ UpperCmdArgs.push_back("-x");
+ UpperCmdArgs.push_back("70");
+ UpperCmdArgs.push_back("4");
+ for (auto Arg : Args.filtered(options::OPT_Mchkptr)) {
+ Arg->claim();
+ }
+ }
+
+ // Set a -x flag for first part of Fortran frontend
+ for (Arg *A : Args.filtered(options::OPT_Hx_EQ)) {
+ A->claim();
+ StringRef Value = A->getValue();
+ auto XFlag = Value.split(",");
+ UpperCmdArgs.push_back("-x");
+ UpperCmdArgs.push_back(Args.MakeArgString(XFlag.first));
+ UpperCmdArgs.push_back(Args.MakeArgString(XFlag.second));
+ }
+
+ // Set a -y flag for first part of Fortran frontend
+ for (Arg *A : Args.filtered(options::OPT_Hy_EQ)) {
+ A->claim();
+ StringRef Value = A->getValue();
+ auto XFlag = Value.split(",");
+ UpperCmdArgs.push_back("-y");
+ UpperCmdArgs.push_back(Args.MakeArgString(XFlag.first));
+ UpperCmdArgs.push_back(Args.MakeArgString(XFlag.second));
+ }
+
+ // Set a -q (debug) flag for first part of Fortran frontend
+ for (Arg *A : Args.filtered(options::OPT_Hq_EQ)) {
+ A->claim();
+ StringRef Value = A->getValue();
+ auto XFlag = Value.split(",");
+ UpperCmdArgs.push_back("-q");
+ UpperCmdArgs.push_back(Args.MakeArgString(XFlag.first));
+ UpperCmdArgs.push_back(Args.MakeArgString(XFlag.second));
+ }
+
+ // Set a -qq (debug) flag for first part of Fortran frontend
+ for (Arg *A : Args.filtered(options::OPT_Hqq_EQ)) {
+ A->claim();
+ StringRef Value = A->getValue();
+ auto XFlag = Value.split(",");
+ UpperCmdArgs.push_back("-qq");
+ UpperCmdArgs.push_back(Args.MakeArgString(XFlag.first));
+ UpperCmdArgs.push_back(Args.MakeArgString(XFlag.second));
+ }
+
+ const char * STBFile = Args.MakeArgString(Stem + ".stb");
+ C.addTempFile(STBFile);
+ UpperCmdArgs.push_back("-stbfile");
+ UpperCmdArgs.push_back(STBFile);
+
+ const char * ModuleExportFile = Args.MakeArgString(Stem + ".cmod");
+ C.addTempFile(ModuleExportFile);
+ UpperCmdArgs.push_back("-modexport");
+ UpperCmdArgs.push_back(ModuleExportFile);
+
+ const char * ModuleIndexFile = Args.MakeArgString(Stem + ".cmdx");
+ C.addTempFile(ModuleIndexFile);
+ UpperCmdArgs.push_back("-modindex");
+ UpperCmdArgs.push_back(ModuleIndexFile);
+
+ UpperCmdArgs.push_back("-output");
+ UpperCmdArgs.push_back(ILMFile);
+
+ SmallString<256> Path;
+ if(Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() > 0) {
+ SmallString<128> TargetInfo;
+ Path = llvm::sys::path::parent_path(Output.getFilename());
+ Arg* Tgts = Args.getLastArg(options::OPT_fopenmp_targets_EQ);
+ assert(Tgts && Tgts->getNumValues() &&
+ "OpenMP offloading has to have targets specified.");
+ for (unsigned i = 0; i < Tgts->getNumValues(); ++i) {
+ if (i)
+ TargetInfo += ',';
+ llvm::Triple T(Tgts->getValue(i));
+ TargetInfo += T.getTriple();
+ }
+ UpperCmdArgs.push_back("-fopenmp-targets");
+ UpperCmdArgs.push_back(Args.MakeArgString(TargetInfo.str()));
+ }
+
+ C.addCommand(std::make_unique<Command>(JA, *this, UpperExec, UpperCmdArgs, Inputs));
+
+ // For -fsyntax-only or -E that is it
+ if (Args.hasArg(options::OPT_fsyntax_only) ||
+ Args.hasArg(options::OPT_E)) return;
+
+ /***** Lower part of Fortran frontend *****/
+
+ const char *LowerExec = Args.MakeArgString(getToolChain().GetProgramPath("flang2"));
+
+ // TODO FLANG arg handling
+ LowerCmdArgs.push_back("-fn"); LowerCmdArgs.push_back(Input.getBaseInput());
+ LowerCmdArgs.push_back("-opt"); LowerCmdArgs.push_back(Args.MakeArgString(OptOStr));
+ LowerCmdArgs.push_back("-terse"); LowerCmdArgs.push_back("1");
+ LowerCmdArgs.push_back("-inform"); LowerCmdArgs.push_back("warn");
+ LowerCmdArgs.append(CommonCmdArgs.begin(), CommonCmdArgs.end()); // Append common arguments
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("68"); LowerCmdArgs.push_back("0x1");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("51"); LowerCmdArgs.push_back("0x20");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("119"); LowerCmdArgs.push_back("0xa10000");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("122"); LowerCmdArgs.push_back("0x40");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("123"); LowerCmdArgs.push_back("0x1000");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("127"); LowerCmdArgs.push_back("4");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("127"); LowerCmdArgs.push_back("17");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("19"); LowerCmdArgs.push_back("0x400000");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("28"); LowerCmdArgs.push_back("0x40000");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("120"); LowerCmdArgs.push_back("0x10000000");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("70"); LowerCmdArgs.push_back("0x8000");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("122"); LowerCmdArgs.push_back("1");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("125"); LowerCmdArgs.push_back("0x20000");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("164"); LowerCmdArgs.push_back("0x800000");
+ LowerCmdArgs.push_back("-quad");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("59"); LowerCmdArgs.push_back("4");
+ LowerCmdArgs.push_back("-tp"); LowerCmdArgs.push_back("px");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("120"); LowerCmdArgs.push_back("0x1000"); // debug lite
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("124"); LowerCmdArgs.push_back("0x1400");
+ LowerCmdArgs.push_back("-y"); LowerCmdArgs.push_back("15"); LowerCmdArgs.push_back("2");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("57"); LowerCmdArgs.push_back("0x3b0000");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("58"); LowerCmdArgs.push_back("0x48000000");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("49"); LowerCmdArgs.push_back("0x100");
+ LowerCmdArgs.push_back("-astype"); LowerCmdArgs.push_back("0");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("183"); LowerCmdArgs.push_back("4");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("121"); LowerCmdArgs.push_back("0x800");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("54"); LowerCmdArgs.push_back("0x10");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("70"); LowerCmdArgs.push_back("0x40000000");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("249"); LowerCmdArgs.push_back("90"); // LLVM version
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("124"); LowerCmdArgs.push_back("1");
+ LowerCmdArgs.push_back("-y"); LowerCmdArgs.push_back("163"); LowerCmdArgs.push_back("0xc0000000");
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("189"); LowerCmdArgs.push_back("0x10");
+ LowerCmdArgs.push_back("-y"); LowerCmdArgs.push_back("189"); LowerCmdArgs.push_back("0x4000000");
+
+ // Remove "noinline" attriblute
+ LowerCmdArgs.push_back("-x"); LowerCmdArgs.push_back("183"); LowerCmdArgs.push_back("0x10");
+
+ // Set a -x flag for second part of Fortran frontend
+ for (Arg *A : Args.filtered(options::OPT_Mx_EQ)) {
+ A->claim();
+ StringRef Value = A->getValue();
+ auto XFlag = Value.split(",");
+ LowerCmdArgs.push_back("-x");
+ LowerCmdArgs.push_back(Args.MakeArgString(XFlag.first));
+ LowerCmdArgs.push_back(Args.MakeArgString(XFlag.second));
+ }
+
+ // Set a -y flag for second part of Fortran frontend
+ for (Arg *A : Args.filtered(options::OPT_My_EQ)) {
+ A->claim();
+ StringRef Value = A->getValue();
+ auto XFlag = Value.split(",");
+ LowerCmdArgs.push_back("-y");
+ LowerCmdArgs.push_back(Args.MakeArgString(XFlag.first));
+ LowerCmdArgs.push_back(Args.MakeArgString(XFlag.second));
+ }
+
+ // Set a -q (debug) flag for second part of Fortran frontend
+ for (Arg *A : Args.filtered(options::OPT_Mq_EQ)) {
+ A->claim();
+ StringRef Value = A->getValue();
+ auto XFlag = Value.split(",");
+ LowerCmdArgs.push_back("-q");
+ LowerCmdArgs.push_back(Args.MakeArgString(XFlag.first));
+ LowerCmdArgs.push_back(Args.MakeArgString(XFlag.second));
+ }
+
+ // Set a -qq (debug) flag for second part of Fortran frontend
+ for (Arg *A : Args.filtered(options::OPT_Mqq_EQ)) {
+ A->claim();
+ StringRef Value = A->getValue();
+ auto XFlag = Value.split(",");
+ LowerCmdArgs.push_back("-qq");
+ LowerCmdArgs.push_back(Args.MakeArgString(XFlag.first));
+ LowerCmdArgs.push_back(Args.MakeArgString(XFlag.second));
+ }
+
+ // Pass an arbitrary flag for second part of Fortran frontend
+ for (Arg *A : Args.filtered(options::OPT_Wm_EQ)) {
+ A->claim();
+ StringRef Value = A->getValue();
+ SmallVector<StringRef, 8> PassArgs;
+ Value.split(PassArgs, StringRef(","));
+ for (StringRef PassArg : PassArgs) {
+ LowerCmdArgs.push_back(Args.MakeArgString(PassArg));
+ }
+ }
+
+ LowerCmdArgs.push_back("-stbfile");
+ LowerCmdArgs.push_back(STBFile);
+
+ Path = llvm::sys::path::parent_path(Output.getFilename());
+ bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP);
+
+ /* OpenMP GPU Offload */
+ if(Args.getAllArgValues(options::OPT_fopenmp_targets_EQ).size() > 0) {
+ SmallString<128> TargetInfo;//("-fopenmp-targets ");
+ SmallString<256> TargetInfoAsm;//("-fopenmp-targets-asm ");
+
+ Arg* Tgts = Args.getLastArg(options::OPT_fopenmp_targets_EQ);
+ assert(Tgts && Tgts->getNumValues() &&
+ "OpenMP offloading has to have targets specified.");
+ for (unsigned i = 0; i < Tgts->getNumValues(); ++i) {
+ if (i)
+ TargetInfo += ',';
+ // We need to get the string from the triple because it may be not exactly
+ // the same as the one we get directly from the arguments.
+ llvm::Triple T(Tgts->getValue(i));
+ TargetInfo += T.getTriple();
+ // We also need to give a output file
+ TargetInfoAsm += Path;
+ TargetInfoAsm += "/";
+ TargetInfoAsm += Stem;
+ TargetInfoAsm += "-";
+ TargetInfoAsm += T.getTriple();
+ TargetInfoAsm += ".ll";
+ }
+ // The driver is aware that flang2 can generate multiple files at the same time.
+ // We mimic it here by exchanging the output files.
+ // The driver always uses the output file of -asm.
+ LowerCmdArgs.push_back("-fopenmp-targets");
+ LowerCmdArgs.push_back(Args.MakeArgString(TargetInfo.str()));
+ if(IsOpenMPDevice) {
+ LowerCmdArgs.push_back("-fopenmp-targets-asm");
+ LowerCmdArgs.push_back(Args.MakeArgString(OutFile));
+ LowerCmdArgs.push_back("-asm");
+ LowerCmdArgs.push_back(Args.MakeArgString(TargetInfoAsm.str()));
+ } else {
+ LowerCmdArgs.push_back("-fopenmp-targets-asm");
+ LowerCmdArgs.push_back(Args.MakeArgString(TargetInfoAsm.str()));
+ LowerCmdArgs.push_back("-asm");
+ LowerCmdArgs.push_back(Args.MakeArgString(OutFile));
+ }
+ } else {
+ LowerCmdArgs.push_back("-asm");
+ LowerCmdArgs.push_back(Args.MakeArgString(OutFile));
+ }
+
+ C.addCommand(std::make_unique<Command>(JA, *this, LowerExec, LowerCmdArgs, Inputs));
+}
+
diff --git a/clang/lib/Driver/ToolChains/Flang1.h b/clang/lib/Driver/ToolChains/Flang1.h
new file mode 100644
index 000000000000..2c3eb7c895a0
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/Flang1.h
@@ -0,0 +1,50 @@
+//===--- Flang.h - Flang Tool and ToolChain Implementations ====-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_Flang_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_Flang_H
+
+#include "MSVC.h"
+#include "clang/Basic/DebugInfoOptions.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/Types.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Option/Option.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+namespace driver {
+
+namespace tools {
+
+/// \brief Flang Fortran frontend
+class LLVM_LIBRARY_VISIBILITY FlangFrontend : public Tool {
+public:
+ FlangFrontend(const ToolChain &TC)
+ : Tool("flang:frontend",
+ "Fortran frontend to LLVM", TC,
+ RF_Full) {}
+
+ bool hasGoodDiagnostics() const override { return true; }
+ bool hasIntegratedAssembler() const override { return false; }
+ bool hasIntegratedCPP() const override { return false; }
+
+ void ConstructJob(Compilation &C, const JobAction &JA,
+ const InputInfo &Output, const InputInfoList &Inputs,
+ const llvm::opt::ArgList &TCArgs,
+ const char *LinkingOutput) const override;
+};
+
+} // end namespace tools
+
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CLANG_H
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index e8ef881e89ac..61ad241eef70 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -527,6 +527,16 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// The profile runtime also needs access to system libraries.
getToolChain().addProfileRTLibs(Args, CmdArgs);
+ // Add Fortran runtime libraries
+ if (needFortranLibs(D, Args)) {
+ ToolChain.AddFortranStdlibLibArgs(Args, CmdArgs);
+ } else {
+ // Claim "no Flang libraries" arguments if any
+ for (auto Arg : Args.filtered(options::OPT_noFlangLibs)) {
+ Arg->claim();
+ }
+ }
+
if (D.CCCIsCXX() &&
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
if (ToolChain.ShouldLinkCXXStdlib(Args)) {
diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
index 6532c899492a..97067947686a 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -647,6 +647,194 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const {
return "/" + LibDir + "/" + Loader;
}
+/// Convert path list to Fortran frontend argument
+static void AddFlangSysIncludeArg(const ArgList &DriverArgs,
+ ArgStringList &Flang1Args,
+ ToolChain::path_list IncludePathList) {
+ std::string ArgValue; // Path argument value
+
+ // Make up argument value consisting of paths separated by colons
+ bool first = true;
+ for (auto P : IncludePathList) {
+ if (first) {
+ first = false;
+ } else {
+ ArgValue += ":";
+ }
+ ArgValue += P;
+ }
+
+ // Add the argument
+ Flang1Args.push_back("-stdinc");
+ Flang1Args.push_back(DriverArgs.MakeArgString(ArgValue));
+}
+
+void Linux::AddFlangSystemIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &Flang1Args) const {
+ path_list IncludePathList;
+ const Driver &D = getDriver();
+ std::string SysRoot = computeSysRoot();
+
+ if (DriverArgs.hasArg(options::OPT_nostdinc))
+ return;
+
+ {
+ SmallString<128> P(D.InstalledDir);
+ llvm::sys::path::append(P, "../include");
+ IncludePathList.push_back(P.str());
+ }
+
+ if (!DriverArgs.hasArg(options::OPT_nostdlibinc))
+ IncludePathList.push_back(SysRoot + "/usr/local/include");
+
+ if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
+ SmallString<128> P(D.ResourceDir);
+ llvm::sys::path::append(P, "include");
+ IncludePathList.push_back(P.str());
+ }
+
+ if (DriverArgs.hasArg(options::OPT_nostdlibinc)) {
+ AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList);
+ return;
+ }
+
+ // Check for configure-time C include directories.
+ StringRef CIncludeDirs(C_INCLUDE_DIRS);
+ if (CIncludeDirs != "") {
+ SmallVector<StringRef, 5> dirs;
+ CIncludeDirs.split(dirs, ":");
+ for (StringRef dir : dirs) {
+ StringRef Prefix =
+ llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : "";
+ IncludePathList.push_back(Prefix.str() + dir.str());
+ }
+ AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList);
+ return;
+ }
+
+ // Lacking those, try to detect the correct set of system includes for the
+ // target triple.
+
+ // Add include directories specific to the selected multilib set and multilib.
+ if (GCCInstallation.isValid()) {
+ const auto &Callback = Multilibs.includeDirsCallback();
+ if (Callback) {
+ for (const auto &Path : Callback(GCCInstallation.getMultilib()))
+ addExternCSystemIncludeIfExists(
+ DriverArgs, Flang1Args, GCCInstallation.getInstallPath() + Path);
+ }
+ }
+
+ // Implement generic Debian multiarch support.
+ const StringRef X86_64MultiarchIncludeDirs[] = {
+ "/usr/include/x86_64-linux-gnu",
+
+ // FIXME: These are older forms of multiarch. It's not clear that they're
+ // in use in any released version of Debian, so we should consider
+ // removing them.
+ "/usr/include/i686-linux-gnu/64", "/usr/include/i486-linux-gnu/64"};
+ const StringRef X86MultiarchIncludeDirs[] = {
+ "/usr/include/i386-linux-gnu",
+
+ // FIXME: These are older forms of multiarch. It's not clear that they're
+ // in use in any released version of Debian, so we should consider
+ // removing them.
+ "/usr/include/x86_64-linux-gnu/32", "/usr/include/i686-linux-gnu",
+ "/usr/include/i486-linux-gnu"};
+ const StringRef AArch64MultiarchIncludeDirs[] = {
+ "/usr/include/aarch64-linux-gnu"};
+ const StringRef ARMMultiarchIncludeDirs[] = {
+ "/usr/include/arm-linux-gnueabi"};
+ const StringRef ARMHFMultiarchIncludeDirs[] = {
+ "/usr/include/arm-linux-gnueabihf"};
+ const StringRef MIPSMultiarchIncludeDirs[] = {"/usr/include/mips-linux-gnu"};
+ const StringRef MIPSELMultiarchIncludeDirs[] = {
+ "/usr/include/mipsel-linux-gnu"};
+ const StringRef MIPS64MultiarchIncludeDirs[] = {
+ "/usr/include/mips64-linux-gnu", "/usr/include/mips64-linux-gnuabi64"};
+ const StringRef MIPS64ELMultiarchIncludeDirs[] = {
+ "/usr/include/mips64el-linux-gnu",
+ "/usr/include/mips64el-linux-gnuabi64"};
+ const StringRef PPCMultiarchIncludeDirs[] = {
+ "/usr/include/powerpc-linux-gnu"};
+ const StringRef PPC64MultiarchIncludeDirs[] = {
+ "/usr/include/powerpc64-linux-gnu"};
+ const StringRef PPC64LEMultiarchIncludeDirs[] = {
+ "/usr/include/powerpc64le-linux-gnu"};
+ const StringRef SparcMultiarchIncludeDirs[] = {
+ "/usr/include/sparc-linux-gnu"};
+ const StringRef Sparc64MultiarchIncludeDirs[] = {
+ "/usr/include/sparc64-linux-gnu"};
+ ArrayRef<StringRef> MultiarchIncludeDirs;
+ switch (getTriple().getArch()) {
+ case llvm::Triple::x86_64:
+ MultiarchIncludeDirs = X86_64MultiarchIncludeDirs;
+ break;
+ case llvm::Triple::x86:
+ MultiarchIncludeDirs = X86MultiarchIncludeDirs;
+ break;
+ case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_be:
+ MultiarchIncludeDirs = AArch64MultiarchIncludeDirs;
+ break;
+ case llvm::Triple::arm:
+ if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
+ MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs;
+ else
+ MultiarchIncludeDirs = ARMMultiarchIncludeDirs;
+ break;
+ case llvm::Triple::mips:
+ MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
+ break;
+ case llvm::Triple::mipsel:
+ MultiarchIncludeDirs = MIPSELMultiarchIncludeDirs;
+ break;
+ case llvm::Triple::mips64:
+ MultiarchIncludeDirs = MIPS64MultiarchIncludeDirs;
+ break;
+ case llvm::Triple::mips64el:
+ MultiarchIncludeDirs = MIPS64ELMultiarchIncludeDirs;
+ break;
+ case llvm::Triple::ppc:
+ MultiarchIncludeDirs = PPCMultiarchIncludeDirs;
+ break;
+ case llvm::Triple::ppc64:
+ MultiarchIncludeDirs = PPC64MultiarchIncludeDirs;
+ break;
+ case llvm::Triple::ppc64le:
+ MultiarchIncludeDirs = PPC64LEMultiarchIncludeDirs;
+ break;
+ case llvm::Triple::sparc:
+ MultiarchIncludeDirs = SparcMultiarchIncludeDirs;
+ break;
+ case llvm::Triple::sparcv9:
+ MultiarchIncludeDirs = Sparc64MultiarchIncludeDirs;
+ break;
+ default:
+ break;
+ }
+ for (StringRef Dir : MultiarchIncludeDirs) {
+ if (llvm::sys::fs::exists(SysRoot + Dir)) {
+ IncludePathList.push_back(SysRoot + Dir.str());
+ break;
+ }
+ }
+
+ if (getTriple().getOS() == llvm::Triple::RTEMS) {
+ AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList);
+ return;
+ }
+
+ // Add an include of '/include' directly. This isn't provided by default by
+ // system GCCs, but is often used with cross-compiling GCCs, and harmless to
+ // add even when Clang is acting as-if it were a system compiler.
+ IncludePathList.push_back(SysRoot + "/include");
+
+ IncludePathList.push_back(SysRoot + "/usr/include");
+
+ AddFlangSysIncludeArg(DriverArgs, Flang1Args, IncludePathList);
+}
+
void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
const Driver &D = getDriver();
diff --git a/clang/lib/Driver/ToolChains/Linux.h b/clang/lib/Driver/ToolChains/Linux.h
index 923ebecbd215..50471c265ffc 100644
--- a/clang/lib/Driver/ToolChains/Linux.h
+++ b/clang/lib/Driver/ToolChains/Linux.h
@@ -23,6 +23,9 @@ class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF {
bool HasNativeLLVMSupport() const override;
+ void
+ AddFlangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &Flang1Args) const override;
void
AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp
old mode 100644
new mode 100755
index 7d83be2521e7..2f2d46cfde66
--- a/clang/lib/Driver/Types.cpp
+++ b/clang/lib/Driver/Types.cpp
@@ -123,6 +123,8 @@ bool types::isAcceptedByClang(ID Id) {
case TY_Asm:
case TY_C: case TY_PP_C:
+ case TY_F_FreeForm: case TY_PP_F_FreeForm:
+ case TY_F_FixedForm: case TY_PP_F_FixedForm:
case TY_CL:
case TY_CUDA: case TY_PP_CUDA:
case TY_CUDA_DEVICE:
@@ -217,11 +219,33 @@ bool types::isFortran(ID Id) {
default:
return false;
- case TY_Fortran: case TY_PP_Fortran:
+#ifdef USE_CLASSIC_FLANG
+ case TY_F_FreeForm:
+ case TY_PP_F_FreeForm:
+ case TY_F_FixedForm:
+ case TY_PP_F_FixedForm:
+#else
+ case TY_Fortran:
+ case TY_PP_Fortran:
+#endif
return true;
}
}
+bool types::isFreeFormFortran(ID Id) {
+ if (!isFortran(Id))
+ return false;
+
+ return (Id == TY_F_FreeForm || Id == TY_PP_F_FreeForm);
+}
+
+bool types::isFixedFormFortran(ID Id) {
+ if (!isFortran(Id))
+ return false;
+
+ return (Id == TY_F_FixedForm || Id == TY_PP_F_FixedForm);
+}
+
bool types::isSrcFile(ID Id) {
return Id != TY_Object && getPreprocessedType(Id) != TY_INVALID;
}
@@ -230,8 +254,8 @@ types::ID types::lookupTypeForExtension(llvm::StringRef Ext) {
return llvm::StringSwitch<types::ID>(Ext)
.Case("c", TY_C)
.Case("C", TY_CXX)
- .Case("F", TY_Fortran)
- .Case("f", TY_PP_Fortran)
+ .Case("F", TY_F_FixedForm)
+ .Case("f", TY_PP_F_FixedForm)
.Case("h", TY_CHeader)
.Case("H", TY_CXXHeader)
.Case("i", TY_PP_C)
@@ -264,6 +288,20 @@ types::ID types::lookupTypeForExtension(llvm::StringRef Ext) {
.Case("cui", TY_PP_CUDA)
.Case("cxx", TY_CXX)
.Case("CXX", TY_CXX)
+#ifdef USE_CLASSIC_FLANG
+ .Case("for", TY_PP_F_FixedForm)
+ .Case("FOR", TY_PP_F_FixedForm)
+ .Case("fpp", TY_F_FixedForm)
+ .Case("FPP", TY_F_FixedForm)
+ .Case("f90", TY_PP_F_FreeForm)
+ .Case("f95", TY_PP_F_FreeForm)
+ .Case("f03", TY_PP_F_FreeForm)
+ .Case("f08", TY_PP_F_FreeForm)
+ .Case("F90", TY_F_FreeForm)
+ .Case("F95", TY_F_FreeForm)
+ .Case("F03", TY_F_FreeForm)
+ .Case("F08", TY_F_FreeForm)
+#else
.Case("F90", TY_Fortran)
.Case("f90", TY_PP_Fortran)
.Case("F95", TY_Fortran)
@@ -272,6 +310,7 @@ types::ID types::lookupTypeForExtension(llvm::StringRef Ext) {
.Case("FOR", TY_PP_Fortran)
.Case("fpp", TY_Fortran)
.Case("FPP", TY_Fortran)
+#endif
.Case("gch", TY_PCH)
.Case("hip", TY_HIP)
.Case("hpp", TY_CXXHeader)
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index e98a407ac42f..d30d8aa7fc91 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -720,6 +720,10 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.setVecLib(CodeGenOptions::MASSV);
else if (Name == "SVML")
Opts.setVecLib(CodeGenOptions::SVML);
+#ifdef FLANG_LLVM_EXTENSIONS
+ else if (Name == "PGMATH")
+ Opts.setVecLib(CodeGenOptions::PGMATH);
+#endif
else if (Name == "none")
Opts.setVecLib(CodeGenOptions::NoLibrary);
else
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index c273cb96d9b9..7ab33d5847e9 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -159,26 +159,6 @@ static void DefineFloatMacros(MacroBuilder &Builder, StringRef Prefix,
Builder.defineMacro(DefPrefix + "MIN__", Twine(Min)+Ext);
}
-
-/// DefineTypeSize - Emit a macro to the predefines buffer that declares a macro
-/// named MacroName with the max value for a type with width 'TypeWidth' a
-/// signedness of 'isSigned' and with a value suffix of 'ValSuffix' (e.g. LL).
-static void DefineTypeSize(const Twine &MacroName, unsigned TypeWidth,
- StringRef ValSuffix, bool isSigned,
- MacroBuilder &Builder) {
- llvm::APInt MaxVal = isSigned ? llvm::APInt::getSignedMaxValue(TypeWidth)
- : llvm::APInt::getMaxValue(TypeWidth);
- Builder.defineMacro(MacroName, MaxVal.toString(10, isSigned) + ValSuffix);
-}
-
-/// DefineTypeSize - An overloaded helper that uses TargetInfo to determine
-/// the width, suffix, and signedness of the given type
-static void DefineTypeSize(const Twine &MacroName, TargetInfo::IntType Ty,
- const TargetInfo &TI, MacroBuilder &Builder) {
- DefineTypeSize(MacroName, TI.getTypeWidth(Ty), TI.getTypeConstantSuffix(Ty),
- TI.isTypeSigned(Ty), Builder);
-}
-
static void DefineFmt(const Twine &Prefix, TargetInfo::IntType Ty,
const TargetInfo &TI, MacroBuilder &Builder) {
bool IsSigned = TI.isTypeSigned(Ty);
diff --git a/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp b/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
index a75d2a630cf4..86cea5a5b96f 100644
--- a/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
+++ b/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
@@ -646,6 +646,8 @@ CreateFileHandler(MemoryBuffer &FirstInput) {
return std::make_unique<TextFileHandler>(/*Comment=*/"#");
if (FilesType == "ll")
return std::make_unique<TextFileHandler>(/*Comment=*/";");
+ if (FilesType == "f95")
+ return std::make_unique<TextFileHandler>(/*Comment=*/"!");
if (FilesType == "bc")
return std::make_unique<BinaryFileHandler>();
if (FilesType == "s")
diff --git a/clang/tools/driver/CMakeLists.txt b/clang/tools/driver/CMakeLists.txt
index 2b783cff0955..b0d6172f845d 100644
--- a/clang/tools/driver/CMakeLists.txt
+++ b/clang/tools/driver/CMakeLists.txt
@@ -63,7 +63,7 @@ endif()
add_dependencies(clang clang-resource-headers)
if(NOT CLANG_LINKS_TO_CREATE)
- set(CLANG_LINKS_TO_CREATE clang++ clang-cl clang-cpp)
+ set(CLANG_LINKS_TO_CREATE clang++ clang-cl clang-cpp flang)
endif()
foreach(link ${CLANG_LINKS_TO_CREATE})
More information about the llvm-branch-commits
mailing list