diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 086aedefc1187..263d1edf141a0 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -6589,12 +6589,6 @@ def J : JoinedOrSeparate<["-"], "J">, Group, Alias; -let Visibility = [FlangOption] in { -def no_fortran_main : Flag<["-"], "fno-fortran-main">, - Visibility<[FlangOption]>, Group, - HelpText<"Do not include Fortran_main.a (provided by Flang) when linking">; -} // let Visibility = [ FlangOption ] - //===----------------------------------------------------------------------===// // FC1 Options //===----------------------------------------------------------------------===// diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index b65b96db16bd7..fec11c7e716fd 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1191,118 +1191,10 @@ bool tools::addOpenMPRuntime(const Compilation &C, ArgStringList &CmdArgs, return true; } -/// Determines if --whole-archive is active in the list of arguments. -static bool isWholeArchivePresent(const ArgList &Args) { - bool WholeArchiveActive = false; - for (auto *Arg : Args.filtered(options::OPT_Wl_COMMA)) { - if (Arg) { - for (StringRef ArgValue : Arg->getValues()) { - if (ArgValue == "--whole-archive") - WholeArchiveActive = true; - if (ArgValue == "--no-whole-archive") - WholeArchiveActive = false; - } - } - } - - return WholeArchiveActive; -} - -/// Determine if driver is invoked to create a shared object library (-static) -static bool isSharedLinkage(const ArgList &Args) { - return Args.hasArg(options::OPT_shared); -} - -/// Determine if driver is invoked to create a static object library (-shared) -static bool isStaticLinkage(const ArgList &Args) { - return Args.hasArg(options::OPT_static); -} - -/// Add Fortran runtime libs for MSVC -static void addFortranRuntimeLibsMSVC(const ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) { - unsigned RTOptionID = options::OPT__SLASH_MT; - if (auto *rtl = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) { - RTOptionID = llvm::StringSwitch(rtl->getValue()) - .Case("static", options::OPT__SLASH_MT) - .Case("static_dbg", options::OPT__SLASH_MTd) - .Case("dll", options::OPT__SLASH_MD) - .Case("dll_dbg", options::OPT__SLASH_MDd) - .Default(options::OPT__SLASH_MT); - } - switch (RTOptionID) { - case options::OPT__SLASH_MT: - CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.static.lib"); - break; - case options::OPT__SLASH_MTd: - CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.static_dbg.lib"); - break; - case options::OPT__SLASH_MD: - CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.dynamic.lib"); - break; - case options::OPT__SLASH_MDd: - CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.dynamic_dbg.lib"); - break; - } -} - -// Add FortranMain runtime lib -static void addFortranMain(const ToolChain &TC, const ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) { - // 0. Shared-library linkage - // If we are attempting to link a library, we should not add - // -lFortran_main.a to the link line, as the `main` symbol is not - // required for a library and should also be provided by one of - // the translation units of the code that this shared library - // will be linked against eventually. - if (isSharedLinkage(Args) || isStaticLinkage(Args)) { - return; - } - - // 1. MSVC - if (TC.getTriple().isKnownWindowsMSVCEnvironment()) { - addFortranRuntimeLibsMSVC(Args, CmdArgs); - return; - } - - // 2. GNU and similar - const Driver &D = TC.getDriver(); - const char *FortranMainLinkFlag = "-lFortran_main"; - - // Warn if the user added `-lFortran_main` - this library is an implementation - // detail of Flang and should be handled automaticaly by the driver. - for (const char *arg : CmdArgs) { - if (strncmp(arg, FortranMainLinkFlag, strlen(FortranMainLinkFlag)) == 0) - D.Diag(diag::warn_drv_deprecated_custom) - << FortranMainLinkFlag - << "see the Flang driver documentation for correct usage"; - } - - // The --whole-archive option needs to be part of the link line to make - // sure that the main() function from Fortran_main.a is pulled in by the - // linker. However, it shouldn't be used if it's already active. - // TODO: Find an equivalent of `--whole-archive` for Darwin and AIX. - if (!isWholeArchivePresent(Args) && !TC.getTriple().isMacOSX() && - !TC.getTriple().isOSAIX()) { - CmdArgs.push_back("--whole-archive"); - CmdArgs.push_back(FortranMainLinkFlag); - CmdArgs.push_back("--no-whole-archive"); - return; - } - - CmdArgs.push_back(FortranMainLinkFlag); -} - /// Add Fortran runtime libs void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args, llvm::opt::ArgStringList &CmdArgs) { - // 1. Link FortranMain - // FortranMain depends on FortranRuntime, so needs to be listed first. If - // -fno-fortran-main has been passed, skip linking Fortran_main.a - if (!Args.hasArg(options::OPT_no_fortran_main)) - addFortranMain(TC, Args, CmdArgs); - - // 2. Link FortranRuntime and FortranDecimal + // Link FortranRuntime and FortranDecimal // These are handled earlier on Windows by telling the frontend driver to // add the correct libraries to link against as dependents in the object // file. diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 6d93c1f3d7034..8955b9fb653c2 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -282,7 +282,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, assert(TC.getTriple().isKnownWindowsMSVCEnvironment() && "can only add VS runtime library on Windows!"); // if -fno-fortran-main has been passed, skip linking Fortran_main.a - bool LinkFortranMain = !Args.hasArg(options::OPT_no_fortran_main); if (TC.getTriple().isKnownWindowsMSVCEnvironment()) { CmdArgs.push_back(Args.MakeArgString( "--dependent-lib=" + TC.getCompilerRTBasename(Args, "builtins"))); @@ -300,8 +299,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, case options::OPT__SLASH_MT: CmdArgs.push_back("-D_MT"); CmdArgs.push_back("--dependent-lib=libcmt"); - if (LinkFortranMain) - CmdArgs.push_back("--dependent-lib=Fortran_main.static.lib"); CmdArgs.push_back("--dependent-lib=FortranRuntime.static.lib"); CmdArgs.push_back("--dependent-lib=FortranDecimal.static.lib"); break; @@ -309,8 +306,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, CmdArgs.push_back("-D_MT"); CmdArgs.push_back("-D_DEBUG"); CmdArgs.push_back("--dependent-lib=libcmtd"); - if (LinkFortranMain) - CmdArgs.push_back("--dependent-lib=Fortran_main.static_dbg.lib"); CmdArgs.push_back("--dependent-lib=FortranRuntime.static_dbg.lib"); CmdArgs.push_back("--dependent-lib=FortranDecimal.static_dbg.lib"); break; @@ -318,8 +313,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, CmdArgs.push_back("-D_MT"); CmdArgs.push_back("-D_DLL"); CmdArgs.push_back("--dependent-lib=msvcrt"); - if (LinkFortranMain) - CmdArgs.push_back("--dependent-lib=Fortran_main.dynamic.lib"); CmdArgs.push_back("--dependent-lib=FortranRuntime.dynamic.lib"); CmdArgs.push_back("--dependent-lib=FortranDecimal.dynamic.lib"); break; @@ -328,8 +321,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, CmdArgs.push_back("-D_DEBUG"); CmdArgs.push_back("-D_DLL"); CmdArgs.push_back("--dependent-lib=msvcrtd"); - if (LinkFortranMain) - CmdArgs.push_back("--dependent-lib=Fortran_main.dynamic_dbg.lib"); CmdArgs.push_back("--dependent-lib=FortranRuntime.dynamic_dbg.lib"); CmdArgs.push_back("--dependent-lib=FortranDecimal.dynamic_dbg.lib"); break; diff --git a/flang/docs/FlangDriver.md b/flang/docs/FlangDriver.md index ac120b4ff09b6..351595ac0afdb 100644 --- a/flang/docs/FlangDriver.md +++ b/flang/docs/FlangDriver.md @@ -179,46 +179,20 @@ like this: ``` $ flang -v -o example example.o -"/usr/bin/ld" [...] example.o [...] "--whole-archive" "-lFortran_main" -"--no-whole-archive" "-lFortranRuntime" "-lFortranDecimal" [...] +"/usr/bin/ld" [...] example.o [...] "-lFortranRuntime" "-lFortranDecimal" [...] ``` The automatically added libraries are: -* `Fortran_main`: Provides the main entry point `main` that then invokes - `_QQmain` with the Fortran program unit. This library has a dependency to - the `FortranRuntime` library. * `FortranRuntime`: Provides most of the Flang runtime library. * `FortranDecimal`: Provides operations for decimal numbers. -The default is that, when using Flang as the linker, one of the Fortran -translation units provides the program unit and therefore it is assumed that -Fortran is the main code part (calling into C/C++ routines via `BIND (C)` -interfaces). When composing the linker commandline, Flang uses -`--whole-archive` and `--no-whole-archive` (Windows: `/WHOLEARCHIVE:`, -Darwin & AIX: *not implemented yet*) to make sure that all for `Fortran_main` -is processed by the linker. This is done to issue a proper error message when -multiple definitions of `main` occur. This happens, for instance, when linking -a code that has a Fortran program unit with a C/C++ code that also defines a -`main` function. A user may be required to explicitly provide the C++ runtime -libraries at link time (e.g., via `-lstdc++` for STL) - If the code is C/C++ based and invokes Fortran routines, one can either use Clang or Flang as the linker driver. If Clang is used, it will automatically all required runtime libraries needed by C++ (e.g., for STL) to the linker invocation. In this case, one has to explicitly provide the Fortran runtime libraries -`FortranRuntime` and/or `FortranDecimal`. An alternative is to use Flang to link -and use the `-fno-fortran-main` flag. This flag removes -`Fortran_main` from the linker stage and hence requires one of the C/C++ -translation units to provide a definition of the `main` function. In this case, -it may be required to explicitly supply C++ runtime libraries as mentioned above. - -When creating shared or static libraries using Flang with `-shared` or `-static` -flag, Fortran_main is automatically removed from the linker stage (i.e., -`-fno-fortran-main` is on by default). It is assumed that when creating a -static or shared library, the generated library does not need a `main` -function, as a final link stage will occur that will provide the `Fortran_main` -library when creating the final executable. +`FortranRuntime` and/or `FortranDecimal`. An alternative is to use Flang to link. +In this case, it may be required to explicitly supply C++ runtime libraries. On Darwin, the logical root where the system libraries are located (sysroot) must be specified. This can be done with the CMake build flag `DEFAULT_SYSROOT` diff --git a/flang/include/flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h b/flang/include/flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h index 18a24bad39604..216d3bcec137e 100755 --- a/flang/include/flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h +++ b/flang/include/flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h @@ -22,6 +22,7 @@ namespace fir { class FirOpBuilder; +class GlobalOp; } // namespace fir namespace mlir { @@ -37,7 +38,7 @@ namespace fir::runtime { /// Create the list of environment variable defaults for the runtime to set. The /// form of the generated list is defined in the runtime header file /// environment-default-list.h -void genEnvironmentDefaults( +fir::GlobalOp genEnvironmentDefaults( fir::FirOpBuilder &builder, mlir::Location loc, const std::vector &envDefaults); diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Main.h b/flang/include/flang/Optimizer/Builder/Runtime/Main.h new file mode 100644 index 0000000000000..62faf46e1fc77 --- /dev/null +++ b/flang/include/flang/Optimizer/Builder/Runtime/Main.h @@ -0,0 +1,28 @@ +//===-- Main.h - generate main runtime API calls ----------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef FORTRAN_OPTIMIZER_BUILDER_RUNTIME_MAIN_H +#define FORTRAN_OPTIMIZER_BUILDER_RUNTIME_MAIN_H + +namespace mlir { +class Location; +} // namespace mlir + +namespace fir { +class FirOpBuilder; +class GlobalOp; +} // namespace fir + +namespace fir::runtime { + +void genMain(fir::FirOpBuilder &builder, mlir::Location loc, + fir::GlobalOp &env); + +} + +#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_MAIN_H diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index c05bf010b2bd5..b42909eaaacc4 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -36,6 +36,7 @@ #include "flang/Optimizer/Builder/Runtime/Character.h" #include "flang/Optimizer/Builder/Runtime/Derived.h" #include "flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h" +#include "flang/Optimizer/Builder/Runtime/Main.h" #include "flang/Optimizer/Builder/Runtime/Ragged.h" #include "flang/Optimizer/Builder/Runtime/Stop.h" #include "flang/Optimizer/Builder/Todo.h" @@ -359,8 +360,10 @@ class FirConverter : public Fortran::lower::AbstractConverter { // not need to be generated even if no defaults are specified. // However, generating main or changing when the runtime reads // environment variables is required to do so. - fir::runtime::genEnvironmentDefaults(*builder, toLocation(), - bridge.getEnvironmentDefaults()); + auto env = fir::runtime::genEnvironmentDefaults( + *builder, toLocation(), bridge.getEnvironmentDefaults()); + + fir::runtime::genMain(*builder, toLocation(), env); }); finalizeOpenACCLowering(); diff --git a/flang/lib/Optimizer/Builder/CMakeLists.txt b/flang/lib/Optimizer/Builder/CMakeLists.txt index 06339b116cd89..6d0aeb429d35d 100644 --- a/flang/lib/Optimizer/Builder/CMakeLists.txt +++ b/flang/lib/Optimizer/Builder/CMakeLists.txt @@ -23,6 +23,7 @@ add_flang_library(FIRBuilder Runtime/Execute.cpp Runtime/Inquiry.cpp Runtime/Intrinsics.cpp + Runtime/Main.cpp Runtime/Numeric.cpp Runtime/Pointer.cpp Runtime/Ragged.cpp diff --git a/flang/lib/Optimizer/Builder/Runtime/EnvironmentDefaults.cpp b/flang/lib/Optimizer/Builder/Runtime/EnvironmentDefaults.cpp index a11b9339681e3..6e280ac0c06cd 100755 --- a/flang/lib/Optimizer/Builder/Runtime/EnvironmentDefaults.cpp +++ b/flang/lib/Optimizer/Builder/Runtime/EnvironmentDefaults.cpp @@ -13,7 +13,7 @@ #include "flang/Optimizer/Support/InternalNames.h" #include "llvm/ADT/ArrayRef.h" -void fir::runtime::genEnvironmentDefaults( +fir::GlobalOp fir::runtime::genEnvironmentDefaults( fir::FirOpBuilder &builder, mlir::Location loc, const std::vector &envDefaults) { std::string envDefaultListPtrName = @@ -34,14 +34,13 @@ void fir::runtime::genEnvironmentDefaults( // If no defaults were specified, initialize with a null pointer. if (envDefaults.empty()) { - builder.createGlobalConstant( + return builder.createGlobalConstant( loc, envDefaultListRefTy, envDefaultListPtrName, [&](fir::FirOpBuilder &builder) { mlir::Value nullVal = builder.createNullConstant(loc, envDefaultListRefTy); builder.create(loc, nullVal); }); - return; } // Create the Item list. @@ -99,7 +98,7 @@ void fir::runtime::genEnvironmentDefaults( envDefaultListBuilder, linkOnce); // Define the pointer to the list used by the runtime. - builder.createGlobalConstant( + return builder.createGlobalConstant( loc, envDefaultListRefTy, envDefaultListPtrName, [&](fir::FirOpBuilder &builder) { mlir::Value addr = builder.create( diff --git a/flang/lib/Optimizer/Builder/Runtime/Main.cpp b/flang/lib/Optimizer/Builder/Runtime/Main.cpp new file mode 100644 index 0000000000000..3b24fbca9cdb7 --- /dev/null +++ b/flang/lib/Optimizer/Builder/Runtime/Main.cpp @@ -0,0 +1,62 @@ +//===-- Main.cpp - generate main runtime API calls --------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "flang/Optimizer/Builder/Runtime/Main.h" +#include "flang/Optimizer/Builder/BoxValue.h" +#include "flang/Optimizer/Builder/FIRBuilder.h" +#include "flang/Optimizer/Builder/Runtime/RTBuilder.h" +#include "flang/Optimizer/Dialect/FIROps.h" +#include "flang/Optimizer/Dialect/FIRType.h" +#include "flang/Runtime/main.h" +#include "flang/Runtime/stop.h" + +using namespace Fortran::runtime; + +/// Create a `int main(...)` that calls the Fortran entry point +void fir::runtime::genMain(fir::FirOpBuilder &builder, mlir::Location loc, + fir::GlobalOp &env) { + auto *context = builder.getContext(); + auto argcTy = builder.getDefaultIntegerType(); + auto ptrTy = mlir::LLVM::LLVMPointerType::get(context); + + // void ProgramStart(int argc, char** argv, char** envp, + // _QQEnvironmentDefaults* env) + auto startFn = builder.createFunction( + loc, RTNAME_STRING(ProgramStart), + mlir::FunctionType::get(context, {argcTy, ptrTy, ptrTy, ptrTy}, {})); + // void ProgramStop() + auto stopFn = + builder.createFunction(loc, RTNAME_STRING(ProgramEndStatement), + mlir::FunctionType::get(context, {}, {})); + + // int main(int argc, char** argv, char** envp) + auto mainFn = builder.createFunction( + loc, "main", + mlir::FunctionType::get(context, {argcTy, ptrTy, ptrTy}, argcTy)); + // void _QQmain() + auto qqMainFn = builder.createFunction( + loc, "_QQmain", mlir::FunctionType::get(context, {}, {})); + + mainFn.setPublic(); + + auto *block = mainFn.addEntryBlock(); + mlir::OpBuilder::InsertionGuard insertGuard(builder); + builder.setInsertionPointToStart(block); + + llvm::SmallVector args(block->getArguments()); + auto envAddr = + builder.create(loc, env.getType(), env.getSymbol()); + args.push_back(envAddr); + + builder.create(loc, startFn, args); + builder.create(loc, qqMainFn); + builder.create(loc, stopFn); + + mlir::Value ret = builder.createIntegerConstant(loc, argcTy, 0); + builder.create(loc, ret); +} diff --git a/flang/runtime/CMakeLists.txt b/flang/runtime/CMakeLists.txt index bdd0e07bbfd4d..9f25c5dfcad11 100644 --- a/flang/runtime/CMakeLists.txt +++ b/flang/runtime/CMakeLists.txt @@ -103,7 +103,6 @@ append(${NO_LTO_FLAGS} CMAKE_CXX_FLAGS) add_definitions(-U_GLIBCXX_ASSERTIONS) add_definitions(-U_LIBCPP_ENABLE_ASSERTIONS) -add_subdirectory(FortranMain) add_subdirectory(Float128Math) set(sources diff --git a/flang/runtime/FortranMain/CMakeLists.txt b/flang/runtime/FortranMain/CMakeLists.txt deleted file mode 100644 index deb7bd10acf51..0000000000000 --- a/flang/runtime/FortranMain/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -add_flang_library(Fortran_main STATIC INSTALL_WITH_TOOLCHAIN - Fortran_main.c -) -if (DEFINED MSVC) - set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded) - add_flang_library(Fortran_main.static STATIC INSTALL_WITH_TOOLCHAIN - Fortran_main.c - ) - set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL) - add_flang_library(Fortran_main.dynamic STATIC INSTALL_WITH_TOOLCHAIN - Fortran_main.c - ) - set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDebug) - add_flang_library(Fortran_main.static_dbg STATIC INSTALL_WITH_TOOLCHAIN - Fortran_main.c - ) - set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDebugDLL) - add_flang_library(Fortran_main.dynamic_dbg STATIC INSTALL_WITH_TOOLCHAIN - Fortran_main.c - ) - add_dependencies(Fortran_main Fortran_main.static Fortran_main.dynamic - Fortran_main.static_dbg Fortran_main.dynamic_dbg) -endif() diff --git a/flang/runtime/FortranMain/Fortran_main.c b/flang/runtime/FortranMain/Fortran_main.c deleted file mode 100644 index 5d3eaced001eb..0000000000000 --- a/flang/runtime/FortranMain/Fortran_main.c +++ /dev/null @@ -1,23 +0,0 @@ -//===-- runtime/FortranMain/Fortran_main.c --------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "flang/Runtime/main.h" -#include "flang/Runtime/stop.h" - -/* main entry into PROGRAM */ -void _QQmain(void); - -extern const struct EnvironmentDefaultList *_QQEnvironmentDefaults; - -/* C main stub */ -int main(int argc, const char *argv[], const char *envp[]) { - RTNAME(ProgramStart)(argc, argv, envp, _QQEnvironmentDefaults); - _QQmain(); - RTNAME(ProgramEndStatement)(); - return 0; -} diff --git a/flang/test/CMakeLists.txt b/flang/test/CMakeLists.txt index 7d96a72e5f36d..7e036ad539dfc 100644 --- a/flang/test/CMakeLists.txt +++ b/flang/test/CMakeLists.txt @@ -62,7 +62,6 @@ set(FLANG_TEST_DEPENDS llvm-readobj split-file FortranRuntime - Fortran_main FortranDecimal ) if (LLVM_ENABLE_PLUGINS AND NOT WIN32) diff --git a/flang/test/Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90 new file mode 100644 index 0000000000000..706b2cb6c2452 --- /dev/null +++ b/flang/test/Driver/driver-help-hidden.f90 @@ -0,0 +1,172 @@ + +!-------------------------- +! FLANG DRIVER (flang-new) +!-------------------------- +! RUN: %flang --help-hidden 2>&1 | FileCheck %s +! RUN: not %flang -help-hidden 2>&1 | FileCheck %s --check-prefix=ERROR-FLANG + +!---------------------------------------- +! FLANG FRONTEND DRIVER (flang-new -fc1) +!---------------------------------------- +! RUN: not %flang_fc1 --help-hidden 2>&1 | FileCheck %s --check-prefix=ERROR-FLANG-FC1 +! RUN: not %flang_fc1 -help-hidden 2>&1 | FileCheck %s --check-prefix=ERROR-FLANG-FC1 + +! CHECK:USAGE: flang-new +! CHECK-EMPTY: +! CHECK-NEXT: DRIVER OPTIONS: +! CHECK-NEXT: --driver-mode= Set the driver mode to either 'gcc', 'g++', 'cpp', 'cl' or 'flang' +! CHECK-EMPTY: +! CHECK-NEXT:OPTIONS: +! CHECK-NEXT: -### Print (but do not run) the commands to run for this compilation +! CHECK-NEXT: -ccc-print-phases Dump list of actions to perform +! CHECK-NEXT: -cpp Enable predefined and command line preprocessor macros +! CHECK-NEXT: -c Only run preprocess, compile, and assemble steps +! CHECK-NEXT: -dM Print macro definitions in -E mode instead of normal output +! CHECK-NEXT: -dumpmachine Display the compiler's target processor +! CHECK-NEXT: -dumpversion Display the version of the compiler +! CHECK-NEXT: -D = Define to (or 1 if omitted) +! CHECK-NEXT: -emit-llvm Use the LLVM representation for assembler and object files +! CHECK-NEXT: -E Only run the preprocessor +! CHECK-NEXT: -falternative-parameter-statement +! CHECK-NEXT: Enable the old style PARAMETER statement +! CHECK-NEXT: -fapprox-func Allow certain math function calls to be replaced with an approximately equivalent calculation +! CHECK-NEXT: -fbackslash Specify that backslash in string introduces an escape character +! CHECK-NEXT: -fcolor-diagnostics Enable colors in diagnostics +! CHECK-NEXT: -fconvert= Set endian conversion of data for unformatted files +! CHECK-NEXT: -fdefault-double-8 Set the default double precision kind to an 8 byte wide type +! CHECK-NEXT: -fdefault-integer-8 Set the default integer and logical kind to an 8 byte wide type +! CHECK-NEXT: -fdefault-real-8 Set the default real kind to an 8 byte wide type +! CHECK-NEXT: -ffast-math Allow aggressive, lossy floating-point optimizations +! CHECK-NEXT: -ffixed-form Process source files in fixed form +! CHECK-NEXT: -ffixed-line-length= +! CHECK-NEXT: Use as character line width in fixed mode +! CHECK-NEXT: -ffp-contract= Form fused FP ops (e.g. FMAs) +! CHECK-NEXT: -ffree-form Process source files in free form +! CHECK-NEXT: -fhonor-infinities Specify that floating-point optimizations are not allowed that assume arguments and results are not +-inf. +! CHECK-NEXT: -fhonor-nans Specify that floating-point optimizations are not allowed that assume arguments and results are not NANs. +! CHECK-NEXT: -fimplicit-none No implicit typing allowed unless overridden by IMPLICIT statements +! CHECK-NEXT: -finput-charset= Specify the default character set for source files +! CHECK-NEXT: -fintegrated-as Enable the integrated assembler +! CHECK-NEXT: -fintrinsic-modules-path +! CHECK-NEXT: Specify where to find the compiled intrinsic modules +! CHECK-NEXT: -flang-deprecated-no-hlfir +! CHECK-NEXT: Do not use HLFIR lowering (deprecated) +! CHECK-NEXT: -flang-experimental-hlfir +! CHECK-NEXT: Use HLFIR lowering (experimental) +! CHECK-NEXT: -flarge-sizes Use INTEGER(KIND=8) for the result type in size-related intrinsics +! CHECK-NEXT: -flogical-abbreviations Enable logical abbreviations +! CHECK-NEXT: -flto=auto Enable LTO in 'full' mode +! CHECK-NEXT: -flto=jobserver Enable LTO in 'full' mode +! CHECK-NEXT: -flto= Set LTO mode +! CHECK-NEXT: -flto Enable LTO in 'full' mode +! CHECK-NEXT: -fms-runtime-lib= +! CHECK-NEXT: Select Windows run-time library +! CHECK-NEXT: -fno-automatic Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE +! CHECK-NEXT: -fno-color-diagnostics Disable colors in diagnostics +! CHECK-NEXT: -fno-integrated-as Disable the integrated assembler +! CHECK-NEXT: -fno-lto Disable LTO mode (default) +! CHECK-NEXT: -fno-ppc-native-vector-element-order +! CHECK-NEXT: Specifies PowerPC non-native vector element order +! CHECK-NEXT: -fno-rtlib-add-rpath Do not add -rpath with architecture-specific resource directory to the linker flags. When --hip-link is specified, do not add -rpath with HIP runtime library directory to the linker flags +! CHECK-NEXT: -fno-signed-zeros Allow optimizations that ignore the sign of floating point zeros +! CHECK-NEXT: -fno-stack-arrays Allocate array temporaries on the heap (default) +! CHECK-NEXT: -fno-version-loops-for-stride +! CHECK-NEXT: Do not create unit-strided loops (default) +! CHECK-NEXT: -fomit-frame-pointer Omit the frame pointer from functions that don't need it. Some stack unwinding cases, such as profilers and sanitizers, may prefer specifying -fno-omit-frame-pointer. On many targets, -O1 and higher omit the frame pointer by default. -m[no-]omit-leaf-frame-pointer takes precedence for leaf functions +! CHECK-NEXT: -fopenacc Enable OpenACC +! CHECK-NEXT: -fopenmp-assume-no-nested-parallelism +! CHECK-NEXT: Assert no nested parallel regions in the GPU +! CHECK-NEXT: -fopenmp-assume-no-thread-state +! CHECK-NEXT: Assert no thread in a parallel region modifies an ICV +! CHECK-NEXT: -fopenmp-target-debug Enable debugging in the OpenMP offloading device RTL +! CHECK-NEXT: -fopenmp-targets= +! CHECK-NEXT: Specify comma-separated list of triples OpenMP offloading targets to be supported +! CHECK-NEXT: -fopenmp-version= +! CHECK-NEXT: Set OpenMP version (e.g. 45 for OpenMP 4.5, 51 for OpenMP 5.1). Default value is 11 for Flang +! CHECK-NEXT: -fopenmp Parse OpenMP pragmas and generate parallel code. +! CHECK-NEXT: -foptimization-record-file= +! CHECK-NEXT: Specify the output name of the file containing the optimization remarks. Implies -fsave-optimization-record. On Darwin platforms, this cannot be used with multiple -arch options. +! CHECK-NEXT: -foptimization-record-passes= +! CHECK-NEXT: Only include passes which match a specified regular expression in the generated optimization record (by default, include all passes) +! CHECK-NEXT: -fpass-plugin= Load pass plugin from a dynamic shared object file (only with new pass manager). +! CHECK-NEXT: -fppc-native-vector-element-order +! CHECK-NEXT: Specifies PowerPC native vector element order (default) +! CHECK-NEXT: -freciprocal-math Allow division operations to be reassociated +! CHECK-NEXT: -fropi Generate read-only position independent code (ARM only) +! CHECK-NEXT: -frtlib-add-rpath Add -rpath with architecture-specific resource directory to the linker flags. When --hip-link is specified, also add -rpath with HIP runtime library directory to the linker flags +! CHECK-NEXT: -frwpi Generate read-write position independent code (ARM only) +! CHECK-NEXT: -fsave-optimization-record= +! CHECK-NEXT: Generate an optimization record file in a specific format +! CHECK-NEXT: -fsave-optimization-record +! CHECK-NEXT: Generate a YAML optimization record file +! CHECK-NEXT: -fstack-arrays Attempt to allocate array temporaries on the stack, no matter their size +! CHECK-NEXT: -fsyntax-only Run the preprocessor, parser and semantic analysis stages +! CHECK-NEXT: -funderscoring Appends one trailing underscore to external names +! CHECK-NEXT: -fveclib= Use the given vector functions library +! CHECK-NEXT: -fversion-loops-for-stride +! CHECK-NEXT: Create unit-strided versions of loops +! CHECK-NEXT: -fxor-operator Enable .XOR. as a synonym of .NEQV. +! CHECK-NEXT: --gcc-install-dir= +! CHECK-NEXT: Use GCC installation in the specified directory. The directory ends with path components like 'lib{,32,64}/gcc{,-cross}/$triple/$version'. Note: executables (e.g. ld) used by the compiler are not overridden by the selected GCC installation +! CHECK-NEXT: --gcc-toolchain= Specify a directory where Flang can find 'lib{,32,64}/gcc{,-cross}/$triple/$version'. Flang will use the GCC installation with the largest version +! CHECK-NEXT: -gline-directives-only Emit debug line info directives only +! CHECK-NEXT: -gline-tables-only Emit debug line number tables only +! CHECK-NEXT: -gpulibc Link the LLVM C Library for GPUs +! CHECK-NEXT: -g Generate source-level debug information +! CHECK-NEXT: --help-hidden Display help for hidden options +! CHECK-NEXT: -help Display available options +! CHECK-NEXT: -isysroot Set the system root directory (usually /) +! CHECK-NEXT: -I Add directory to the end of the list of include search paths +! CHECK-NEXT: -L Add directory to library search path +! CHECK-NEXT: -march= For a list of available architectures for the target use '-mcpu=help' +! CHECK-NEXT: -mcode-object-version= +! CHECK-NEXT: Specify code object ABI version. Defaults to 5. (AMDGPU only) +! CHECK-NEXT: -mcpu= For a list of available CPUs for the target use '-mcpu=help' +! CHECK-NEXT: -mllvm= Alias for -mllvm +! CHECK-NEXT: -mllvm Additional arguments to forward to LLVM's option processing +! CHECK-NEXT: -mmlir Additional arguments to forward to MLIR's option processing +! CHECK-NEXT: -mno-outline-atomics Don't generate local calls to out-of-line atomic operations +! CHECK-NEXT: -module-dir Put MODULE files in +! CHECK-NEXT: -moutline-atomics Generate local calls to out-of-line atomic operations +! CHECK-NEXT: -mrvv-vector-bits= +! CHECK-NEXT: Specify the size in bits of an RVV vector register +! CHECK-NEXT: -msve-vector-bits= +! CHECK-NEXT: Specify the size in bits of an SVE vector register. Defaults to the vector length agnostic value of "scalable". (AArch64 only) +! CHECK-NEXT: --no-offload-arch= +! CHECK-NEXT: Remove CUDA/HIP offloading device architecture (e.g. sm_35, gfx906) from the list of devices to compile for. 'all' resets the list to its default value. +! CHECK-NEXT: -nocpp Disable predefined and command line preprocessor macros +! CHECK-NEXT: -nogpulib Do not link device library for CUDA/HIP device compilation +! CHECK-NEXT: --offload-arch= Specify an offloading device architecture for CUDA, HIP, or OpenMP. (e.g. sm_35). If 'native' is used the compiler will detect locally installed architectures. For HIP offloading, the device architecture can be followed by target ID features delimited by a colon (e.g. gfx908:xnack+:sramecc-). May be specified more than once. +! CHECK-NEXT: --offload-device-only Only compile for the offloading device. +! CHECK-NEXT: --offload-host-device Compile for both the offloading host and device (default). +! CHECK-NEXT: --offload-host-only Only compile for the offloading host. +! CHECK-NEXT: -o Write output to +! CHECK-NEXT: -pedantic Warn on language extensions +! CHECK-NEXT: -print-effective-triple Print the effective target triple +! CHECK-NEXT: -print-target-triple Print the normalized target triple +! CHECK-NEXT: -pthread Support POSIX threads in generated code +! CHECK-NEXT: -P Disable linemarker output in -E mode +! CHECK-NEXT: -resource-dir The directory which holds the compiler resource files +! CHECK-NEXT: --rocm-path= ROCm installation path, used for finding and automatically linking required bitcode libraries. +! CHECK-NEXT: -Rpass-analysis= Report transformation analysis from optimization passes whose name matches the given POSIX regular expression +! CHECK-NEXT: -Rpass-missed= Report missed transformations by optimization passes whose name matches the given POSIX regular expression +! CHECK-NEXT: -Rpass= Report transformations performed by optimization passes whose name matches the given POSIX regular expression +! CHECK-NEXT: -R Enable the specified remark +! CHECK-NEXT: -save-temps= Save intermediate compilation results. +! CHECK-NEXT: -save-temps Alias for --save-temps=cwd +! CHECK-NEXT: -std= Language standard to compile for +! CHECK-NEXT: -S Only run preprocess and compilation steps +! CHECK-NEXT: --target= Generate code for the given target +! CHECK-NEXT: -U Undefine macro +! CHECK-NEXT: --version Print version information +! CHECK-NEXT: -v Show commands to run and use verbose output +! CHECK-NEXT: -Wl, Pass the comma separated arguments in to the linker +! CHECK-NEXT: -W Enable the specified warning +! CHECK-NEXT: -Xflang Pass to the flang compiler +! CHECK-NEXT: -x Treat subsequent input files as having type + + +! ERROR-FLANG: error: unknown argument '-help-hidden'; did you mean '--help-hidden'? + +! Frontend driver -help-hidden is not supported +! ERROR-FLANG-FC1: error: unknown argument: '{{.*}}' diff --git a/flang/test/Driver/dynamic-linker.f90 b/flang/test/Driver/dynamic-linker.f90 index 7c3f1b5a53fe4..6d5c443ab75cb 100644 --- a/flang/test/Driver/dynamic-linker.f90 +++ b/flang/test/Driver/dynamic-linker.f90 @@ -16,7 +16,6 @@ ! GNU-LINKER-OPTIONS-SAME: "-shared" ! GNU-LINKER-OPTIONS-SAME: "-static" ! GNU-LINKER-OPTIONS-SAME: "-rpath" "/path/to/dir" -! GNU-LINKER-OPTIONS-NOT: "-lFortran_main.a" ! RDYNAMIC-LINKER-OPTION: "{{.*}}ld" ! RDYNAMIC-LINKER-OPTION-SAME: "-export-dynamic" @@ -25,4 +24,3 @@ ! MSVC-LINKER-OPTIONS: "{{.*}}link{{(.exe)?}}" ! MSVC-LINKER-OPTIONS-SAME: "-dll" ! MSVC-LINKER-OPTIONS-SAME: "-rpath" "/path/to/dir" -! MSVC-LINKER-OPTIONS-NOT: "/WHOLEARCHIVE:Fortran_main" diff --git a/flang/test/Driver/emit-mlir.f90 b/flang/test/Driver/emit-mlir.f90 index 191ee13396ef9..83bb8fc1eddcd 100644 --- a/flang/test/Driver/emit-mlir.f90 +++ b/flang/test/Driver/emit-mlir.f90 @@ -19,6 +19,16 @@ ! CHECK-NEXT: %[[VAL_0:.*]] = fir.zero_bits !fir.ref, !fir.ref>>>>> ! CHECK-NEXT: fir.has_value %[[VAL_0]] : !fir.ref, !fir.ref>>>>> ! CHECK-NEXT: } +! CHECK-NEXT: func.func private @_FortranAProgramStart(i32, !llvm.ptr, !llvm.ptr, !llvm.ptr) +! CHECK-NEXT: func.func private @_FortranAProgramEndStatement() +! CHECK-NEXT: func.func @main(%arg0: i32, %arg1: !llvm.ptr, %arg2: !llvm.ptr) -> i32 { +! CHECK-NEXT: %c0_i32 = arith.constant 0 : i32 +! CHECK-NEXT: %0 = fir.address_of(@_QQEnvironmentDefaults) : !fir.ref, !fir.ref>>>>> +! CHECK-NEXT: ir.call @_FortranAProgramStart(%arg0, %arg1, %arg2, %0) {{.*}} : (i32, !llvm.ptr, !llvm.ptr, !fir.ref, !fir.ref>>>>>) +! CHECK-NEXT: fir.call @_QQmain() fastmath : () -> () +! CHECK-NEXT: fir.call @_FortranAProgramEndStatement() {{.*}} : () -> () +! CHECK-NEXT: return %c0_i32 : i32 +! CHECK-NEXT: } ! CHECK-NEXT: } end program diff --git a/flang/test/Driver/linker-flags.f90 b/flang/test/Driver/linker-flags.f90 index 4d3d528b5e99e..02e217494f818 100644 --- a/flang/test/Driver/linker-flags.f90 +++ b/flang/test/Driver/linker-flags.f90 @@ -11,7 +11,6 @@ ! RUN: %flang -### --target=x86_64-unknown-dragonfly %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,UNIX,UNIX-F128%f128-lib ! RUN: %flang -### --target=x86_64-unknown-haiku %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,HAIKU,HAIKU-F128%f128-lib ! RUN: %flang -### --target=x86_64-windows-gnu %S/Inputs/hello.f90 2>&1 | FileCheck %s --check-prefixes=CHECK,MINGW,MINGW-F128%f128-lib -! RUN: %flang -### --target=aarch64-unknown-linux-gnu %S/Inputs/hello.f90 -lFortran_main 2>&1 | FileCheck %s --check-prefixes=DEPRECATED ! NOTE: Clang's driver library, clangDriver, usually adds 'oldnames' on Windows, ! but it is not needed when compiling Fortran code and they might bring in @@ -29,7 +28,6 @@ ! executable and may find the GNU linker from MinGW or Cygwin. ! UNIX-LABEL: "{{.*}}ld{{(\.exe)?}}" ! UNIX-SAME: "[[object_file]]" -! UNIX-SAME: "--whole-archive" "-lFortran_main" "--no-whole-archive" ! UNIX-F128NONE-NOT: FortranFloat128Math ! SOLARIS-F128NONE-NOT: FortranFloat128Math ! UNIX-F128LIBQUADMATH-SAME: "-lFortranFloat128Math" "--as-needed" "-lquadmath" "--no-as-needed" @@ -38,7 +36,6 @@ ! DARWIN-LABEL: "{{.*}}ld{{(\.exe)?}}" ! DARWIN-SAME: "[[object_file]]" -! DARWIN-SAME: -lFortran_main ! DARWIN-F128NONE-NOT: FortranFloat128Math ! DARWIN-F128LIBQUADMATH-SAME: "-lFortranFloat128Math" "--as-needed" "-lquadmath" "--no-as-needed" ! DARWIN-SAME: -lFortranRuntime @@ -46,14 +43,12 @@ ! HAIKU-LABEL: "{{.*}}ld{{(\.exe)?}}" ! HAIKU-SAME: "[[object_file]]" -! HAIKU-SAME: "--whole-archive" "-lFortran_main" "--no-whole-archive" ! HAIKU-F128NONE-NOT: FortranFloat128Math ! HAIKU-F128LIBQUADMATH-SAME: "-lFortranFloat128Math" "--as-needed" "-lquadmath" "--no-as-needed" ! HAIKU-SAME: "-lFortranRuntime" "-lFortranDecimal" ! MINGW-LABEL: "{{.*}}ld{{(\.exe)?}}" ! MINGW-SAME: "[[object_file]]" -! MINGW-SAME: -lFortran_main ! MINGW-F128NONE-NOT: FortranFloat128Math ! MINGW-F128LIBQUADMATH-SAME: "-lFortranFloat128Math" "--as-needed" "-lquadmath" "--no-as-needed" ! MINGW-SAME: -lFortranRuntime @@ -66,6 +61,3 @@ ! MSVC-LABEL: link ! MSVC-SAME: /subsystem:console ! MSVC-SAME: "[[object_file]]" - -! Check that we warn when using -lFortran_main -! DEPRECATED: warning: argument '-lFortran_main' is deprecated, see the Flang driver documentation for correct usage [-Wdeprecated] diff --git a/flang/test/Driver/msvc-dependent-lib-flags.f90 b/flang/test/Driver/msvc-dependent-lib-flags.f90 index 6cfc969e92b20..765917f07d8e7 100644 --- a/flang/test/Driver/msvc-dependent-lib-flags.f90 +++ b/flang/test/Driver/msvc-dependent-lib-flags.f90 @@ -7,7 +7,6 @@ ! MSVC-SAME: --dependent-lib=clang_rt.builtins.lib ! MSVC-SAME: -D_MT ! MSVC-SAME: --dependent-lib=libcmt -! MSVC-SAME: --dependent-lib=Fortran_main.static.lib ! MSVC-SAME: --dependent-lib=FortranRuntime.static.lib ! MSVC-SAME: --dependent-lib=FortranDecimal.static.lib @@ -16,7 +15,6 @@ ! MSVC-DEBUG-SAME: -D_MT ! MSVC-DEBUG-SAME: -D_DEBUG ! MSVC-DEBUG-SAME: --dependent-lib=libcmtd -! MSVC-DEBUG-SAME: --dependent-lib=Fortran_main.static_dbg.lib ! MSVC-DEBUG-SAME: --dependent-lib=FortranRuntime.static_dbg.lib ! MSVC-DEBUG-SAME: --dependent-lib=FortranDecimal.static_dbg.lib @@ -25,7 +23,6 @@ ! MSVC-DLL-SAME: -D_MT ! MSVC-DLL-SAME: -D_DLL ! MSVC-DLL-SAME: --dependent-lib=msvcrt -! MSVC-DLL-SAME: --dependent-lib=Fortran_main.dynamic.lib ! MSVC-DLL-SAME: --dependent-lib=FortranRuntime.dynamic.lib ! MSVC-DLL-SAME: --dependent-lib=FortranDecimal.dynamic.lib @@ -35,6 +32,5 @@ ! MSVC-DLL-DEBUG-SAME: -D_DEBUG ! MSVC-DLL-DEBUG-SAME: -D_DLL ! MSVC-DLL-DEBUG-SAME: --dependent-lib=msvcrtd -! MSVC-DLL-DEBUG-SAME: --dependent-lib=Fortran_main.dynamic_dbg.lib ! MSVC-DLL-DEBUG-SAME: --dependent-lib=FortranRuntime.dynamic_dbg.lib ! MSVC-DLL-DEBUG-SAME: --dependent-lib=FortranDecimal.dynamic_dbg.lib diff --git a/flang/test/Driver/no-duplicate-main.f90 b/flang/test/Driver/no-duplicate-main.f90 index 88f4430828e09..b0bb6c2a2fefb 100644 --- a/flang/test/Driver/no-duplicate-main.f90 +++ b/flang/test/Driver/no-duplicate-main.f90 @@ -4,8 +4,6 @@ ! RUN: %flang -o %t -c %s ! RUN: not %flang -o %t.exe %t %t.c-object 2>&1 -! RUN: %flang -fno-fortran-main -o %t.exe %t %t.c-object 2>&1 - ! TODO: potentially add further checks to ensure that proper ! linker error messages are detected and checked via ! FileCheck. diff --git a/flang/tools/flang-driver/CMakeLists.txt b/flang/tools/flang-driver/CMakeLists.txt index 3ce8b407450d2..ce30ecff028dc 100644 --- a/flang/tools/flang-driver/CMakeLists.txt +++ b/flang/tools/flang-driver/CMakeLists.txt @@ -21,7 +21,6 @@ add_flang_tool(flang-new # unable to generate executables. FortranRuntime FortranDecimal - Fortran_main ) target_link_libraries(flang-new diff --git a/lld/COFF/MinGW.cpp b/lld/COFF/MinGW.cpp index e46f5277a8c36..29c01da9e28f6 100644 --- a/lld/COFF/MinGW.cpp +++ b/lld/COFF/MinGW.cpp @@ -50,7 +50,6 @@ AutoExporter::AutoExporter( "libclang_rt.profile-x86_64", "libc++", "libc++abi", - "libFortran_main", "libFortranRuntime", "libFortranDecimal", "libunwind",