jpenix-quic created this revision. jpenix-quic added reviewers: schweitz, klausler, peixin, awarzynski. jpenix-quic added a project: Flang. Herald added subscribers: mehdi_amini, jdoerfert, mgorny. Herald added a reviewer: sscalpone. Herald added a project: All. jpenix-quic requested review of this revision. Herald added subscribers: cfe-commits, sstefan1, MaskRay. Herald added a reviewer: jdoerfert. Herald added a project: clang.
This follows gfortran's approach of generating a runtime call to set the conversion state for the entire program and takes effect only if the fconvert option is used on the main program (as the runtime call is inserted into _QQmain). Resolves issue: https://github.com/llvm/llvm-project/issues/55961 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D130513 Files: clang/include/clang/Driver/Options.td clang/lib/Driver/ToolChains/Flang.cpp flang/include/flang/Frontend/FrontendOptions.h flang/include/flang/Lower/Bridge.h flang/include/flang/Optimizer/Builder/Runtime/Convert.h flang/include/flang/Runtime/convert.h flang/include/flang/Runtime/main.h flang/lib/Frontend/CompilerInvocation.cpp flang/lib/Frontend/FrontendActions.cpp flang/lib/Lower/Bridge.cpp flang/lib/Optimizer/Builder/CMakeLists.txt flang/lib/Optimizer/Builder/Runtime/Convert.cpp flang/runtime/environment.cpp flang/runtime/environment.h flang/runtime/main.cpp flang/test/Driver/convert.f90 flang/test/Driver/driver-help-hidden.f90 flang/test/Driver/driver-help.f90 flang/test/Driver/frontend-forwarding.f90 flang/tools/bbc/bbc.cpp flang/unittests/Runtime/ExternalIOTest.cpp
Index: flang/unittests/Runtime/ExternalIOTest.cpp =================================================================== --- flang/unittests/Runtime/ExternalIOTest.cpp +++ flang/unittests/Runtime/ExternalIOTest.cpp @@ -149,6 +149,67 @@ << "EndIoStatement() for Close"; } +TEST(ExternalIOTests, TestDirectUnformattedSwappedConvert) { + // OPEN(NEWUNIT=unit,ACCESS='DIRECT',ACTION='READWRITE',& + // FORM='UNFORMATTED',RECL=8,STATUS='SCRATCH',CONVERT='NATIVE') + auto *io{IONAME(BeginOpenNewUnit)(__FILE__, __LINE__)}; + ASSERT_TRUE(IONAME(SetAccess)(io, "DIRECT", 6)) << "SetAccess(DIRECT)"; + ASSERT_TRUE(IONAME(SetAction)(io, "READWRITE", 9)) << "SetAction(READWRITE)"; + ASSERT_TRUE(IONAME(SetForm)(io, "UNFORMATTED", 11)) << "SetForm(UNFORMATTED)"; + ASSERT_TRUE(IONAME(SetConvert)(io, "NATIVE", 6)) << "SetConvert(NATIVE)"; + + std::int64_t buffer; + static constexpr std::size_t recl{sizeof buffer}; + ASSERT_TRUE(IONAME(SetRecl)(io, recl)) << "SetRecl()"; + ASSERT_TRUE(IONAME(SetStatus)(io, "SCRATCH", 7)) << "SetStatus(SCRATCH)"; + + int unit{-1}; + ASSERT_TRUE(IONAME(GetNewUnit)(io, unit)) << "GetNewUnit()"; + ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk) + << "EndIoStatement() for OpenNewUnit"; + + static constexpr int records{10}; + for (int j{1}; j <= records; ++j) { + // WRITE(UNIT=unit,REC=j) j + io = IONAME(BeginUnformattedOutput)(unit, __FILE__, __LINE__); + ASSERT_TRUE(IONAME(SetRec)(io, j)) << "SetRec(" << j << ')'; + buffer = j; + ASSERT_TRUE(IONAME(OutputUnformattedBlock)( + io, reinterpret_cast<const char *>(&buffer), recl, recl)) + << "OutputUnformattedBlock()"; + ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk) + << "EndIoStatement() for OutputUnformattedBlock"; + } + + // Set unformatted conversion to SWAP + RTNAME(ConvertOption)(4); + // OPEN(UNIT=unit,STATUS='OLD') + io = IONAME(BeginOpenUnit)(unit, __FILE__, __LINE__); + ASSERT_TRUE(IONAME(SetStatus)(io, "OLD", 3)) << "SetStatus(OLD)"; + ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk) + << "EndIoStatement() for OpenUnit"; + + for (int j{records}; j >= 1; --j) { + // READ(UNIT=unit,REC=j) n + io = IONAME(BeginUnformattedInput)(unit, __FILE__, __LINE__); + ASSERT_TRUE(IONAME(SetRec)(io, j)) << "SetRec(" << j << ')'; + ASSERT_TRUE(IONAME(InputUnformattedBlock)( + io, reinterpret_cast<char *>(&buffer), recl, recl)) + << "InputUnformattedBlock()"; + ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk) + << "EndIoStatement() for InputUnformattedBlock"; + ASSERT_EQ(buffer >> 56, j) + << "Read back " << (buffer >> 56) << " from direct unformatted record " + << j << ", expected " << j << '\n'; + } + + // CLOSE(UNIT=unit,STATUS='DELETE') + io = IONAME(BeginClose)(unit, __FILE__, __LINE__); + ASSERT_TRUE(IONAME(SetStatus)(io, "DELETE", 6)) << "SetStatus(DELETE)"; + ASSERT_EQ(IONAME(EndIoStatement)(io), IostatOk) + << "EndIoStatement() for Close"; +} + TEST(ExternalIOTests, TestSequentialFixedUnformatted) { // OPEN(NEWUNIT=unit,ACCESS='SEQUENTIAL',ACTION='READWRITE',& // FORM='UNFORMATTED',RECL=8,STATUS='SCRATCH') Index: flang/tools/bbc/bbc.cpp =================================================================== --- flang/tools/bbc/bbc.cpp +++ flang/tools/bbc/bbc.cpp @@ -33,6 +33,7 @@ #include "flang/Parser/parsing.h" #include "flang/Parser/provenance.h" #include "flang/Parser/unparse.h" +#include "flang/Runtime/convert.h" #include "flang/Semantics/expression.h" #include "flang/Semantics/runtime-type-info.h" #include "flang/Semantics/semantics.h" @@ -219,7 +220,7 @@ auto burnside = Fortran::lower::LoweringBridge::create( ctx, defKinds, semanticsContext.intrinsics(), semanticsContext.targetCharacteristics(), parsing.allCooked(), "", - kindMap); + kindMap, Fortran::runtime::Convert::Unknown); burnside.lower(parseTree, semanticsContext); mlir::ModuleOp mlirModule = burnside.getModule(); std::error_code ec; Index: flang/test/Driver/frontend-forwarding.f90 =================================================================== --- flang/test/Driver/frontend-forwarding.f90 +++ flang/test/Driver/frontend-forwarding.f90 @@ -7,6 +7,7 @@ ! RUN: -fdefault-integer-8 \ ! RUN: -fdefault-real-8 \ ! RUN: -flarge-sizes \ +! RUN: -fconvert=little-endian \ ! RUN: -mllvm -print-before-all\ ! RUN: -P \ ! RUN: | FileCheck %s @@ -17,4 +18,5 @@ ! CHECK: "-fdefault-integer-8" ! CHECK: "-fdefault-real-8" ! CHECK: "-flarge-sizes" +! CHECK: "-fconvert=little-endian" ! CHECK: "-mllvm" "-print-before-all" Index: flang/test/Driver/driver-help.f90 =================================================================== --- flang/test/Driver/driver-help.f90 +++ flang/test/Driver/driver-help.f90 @@ -24,6 +24,7 @@ ! HELP-NEXT: Enable the old style PARAMETER statement ! HELP-NEXT: -fbackslash Specify that backslash in string introduces an escape character ! HELP-NEXT: -fcolor-diagnostics Enable colors in diagnostics +! HELP-NEXT: -fconvert=<value> Set endian conversion of data for unformatted files ! HELP-NEXT: -fdefault-double-8 Set the default double precision kind to an 8 byte wide type ! HELP-NEXT: -fdefault-integer-8 Set the default integer kind to an 8 byte wide type ! HELP-NEXT: -fdefault-real-8 Set the default real kind to an 8 byte wide type @@ -78,6 +79,7 @@ ! HELP-FC1-NEXT: Enable the old style PARAMETER statement ! HELP-FC1-NEXT: -fbackslash Specify that backslash in string introduces an escape character ! HELP-FC1-NEXT: -fcolor-diagnostics Enable colors in diagnostics +! HELP-FC1-NEXT: -fconvert=<value> Set endian conversion of data for unformatted files ! HELP-FC1-NEXT: -fdebug-dump-all Dump symbols and the parse tree after the semantic checks ! HELP-FC1-NEXT: -fdebug-dump-parse-tree-no-sema ! HELP-FC1-NEXT: Dump the parse tree (skips the semantic checks) Index: flang/test/Driver/driver-help-hidden.f90 =================================================================== --- flang/test/Driver/driver-help-hidden.f90 +++ flang/test/Driver/driver-help-hidden.f90 @@ -24,6 +24,7 @@ ! CHECK-NEXT: Enable the old style PARAMETER statement ! CHECK-NEXT: -fbackslash Specify that backslash in string introduces an escape character ! CHECK-NEXT: -fcolor-diagnostics Enable colors in diagnostics +! CHECK-NEXT: -fconvert=<value> 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 kind to an 8 byte wide type ! CHECK-NEXT: -fdefault-real-8 Set the default real kind to an 8 byte wide type Index: flang/test/Driver/convert.f90 =================================================================== --- /dev/null +++ flang/test/Driver/convert.f90 @@ -0,0 +1,13 @@ +! Ensure argument -fconvert=<value> works as expected. + +!-------------------------- +! FLANG DRIVER (flang) +!-------------------------- +! RUN: not %flang -fconvert=foobar %s 2>&1 | FileCheck %s --check-prefix=WRONG + +!!----------------------------------------- +! FRONTEND FLANG DRIVER (flang-new -fc1) +!----------------------------------------- +! RUN: not %flang_fc1 -fconvert=foobar %s 2>&1 | FileCheck %s --check-prefix=WRONG + +! WRONG: error: invalid value 'foobar' in '-fconvert=foobar' Index: flang/runtime/main.cpp =================================================================== --- flang/runtime/main.cpp +++ flang/runtime/main.cpp @@ -43,4 +43,19 @@ Fortran::runtime::Convert::Swap; } } + +void RTNAME(ConvertOption)(int i) { + // Defer to the current conversion value to allow the environment variable to + // take precedence even if the command-line option was specified. + if (Fortran::runtime::executionEnvironment.conversion != + Fortran::runtime::Convert::Unknown) + return; + + if (auto convert{Fortran::runtime::GetConvertFromInt(i)}) { + Fortran::runtime::executionEnvironment.conversion = *convert; + } else { + Fortran::runtime::Terminator{__FILE__, __LINE__}.Crash( + "Invalid convert option passed to ConvertOption"); + } +} } Index: flang/runtime/environment.h =================================================================== --- flang/runtime/environment.h +++ flang/runtime/environment.h @@ -10,6 +10,7 @@ #define FORTRAN_RUNTIME_ENVIRONMENT_H_ #include "flang/Decimal/decimal.h" +#include "flang/Runtime/convert.h" #include <optional> namespace Fortran::runtime { @@ -24,10 +25,8 @@ #error host endianness is not known #endif -// External unformatted I/O data conversions -enum class Convert { Unknown, Native, LittleEndian, BigEndian, Swap }; - std::optional<Convert> GetConvertFromString(const char *, std::size_t); +std::optional<Convert> GetConvertFromInt(int); struct ExecutionEnvironment { constexpr ExecutionEnvironment(){}; Index: flang/runtime/environment.cpp =================================================================== --- flang/runtime/environment.cpp +++ flang/runtime/environment.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "environment.h" +#include "flang/Runtime/convert.h" #include "memory.h" #include "tools.h" #include <cstdio> @@ -37,6 +38,15 @@ } } +std::optional<Convert> GetConvertFromInt(int i) { + if (i < static_cast<int>(Convert::Unknown) || + i > static_cast<int>(Convert::Swap)) { + return std::nullopt; + } + + return static_cast<Convert>(i); +} + void ExecutionEnvironment::Configure( int ac, const char *av[], const char *env[]) { argc = ac; Index: flang/lib/Optimizer/Builder/Runtime/Convert.cpp =================================================================== --- /dev/null +++ flang/lib/Optimizer/Builder/Runtime/Convert.cpp @@ -0,0 +1,26 @@ +//===-- Convert.cpp -------------------------------------------------------===// +// +// 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/Convert.h" +#include "flang/Optimizer/Builder/FIRBuilder.h" +#include "flang/Optimizer/Builder/Runtime/RTBuilder.h" +#include "flang/Runtime/convert.h" +#include "flang/Runtime/main.h" + +void fir::runtime::genConvertOption(mlir::Location loc, + fir::FirOpBuilder &builder, + Fortran::runtime::Convert conversion) { + mlir::func::FuncOp func = + fir::runtime::getRuntimeFunc<mkRTKey(ConvertOption)>(loc, builder); + mlir::FunctionType funcTy = func.getFunctionType(); + mlir::Value conversionVal = builder.createIntegerConstant( + loc, funcTy.getInput(0), static_cast<int>(conversion)); + llvm::SmallVector<mlir::Value> args = + fir::runtime::createArguments(builder, loc, funcTy, conversionVal); + builder.create<fir::CallOp>(loc, func, args); +} Index: flang/lib/Optimizer/Builder/CMakeLists.txt =================================================================== --- flang/lib/Optimizer/Builder/CMakeLists.txt +++ flang/lib/Optimizer/Builder/CMakeLists.txt @@ -11,6 +11,7 @@ Runtime/Assign.cpp Runtime/Character.cpp Runtime/Command.cpp + Runtime/Convert.cpp Runtime/Derived.cpp Runtime/Inquiry.cpp Runtime/Numeric.cpp Index: flang/lib/Lower/Bridge.cpp =================================================================== --- flang/lib/Lower/Bridge.cpp +++ flang/lib/Lower/Bridge.cpp @@ -31,6 +31,8 @@ #include "flang/Optimizer/Builder/Character.h" #include "flang/Optimizer/Builder/FIRBuilder.h" #include "flang/Optimizer/Builder/Runtime/Character.h" +#include "flang/Optimizer/Builder/Runtime/Convert.h" +#include "flang/Optimizer/Builder/Runtime/RTBuilder.h" #include "flang/Optimizer/Builder/Runtime/Ragged.h" #include "flang/Optimizer/Builder/Todo.h" #include "flang/Optimizer/Dialect/FIRAttr.h" @@ -41,6 +43,7 @@ #include "flang/Optimizer/Support/InternalNames.h" #include "flang/Optimizer/Transforms/Passes.h" #include "flang/Parser/parse-tree.h" +#include "flang/Runtime/convert.h" #include "flang/Runtime/iostat.h" #include "flang/Semantics/tools.h" #include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h" @@ -2752,6 +2755,12 @@ builder->create<fir::StoreOp>(loc, zero, altResult); } + if (funit.isMainProgram()) { + auto conversion = bridge.getConversion(); + if (conversion != Fortran::runtime::Convert::Unknown) + fir::runtime::genConvertOption(toLocation(), *builder, conversion); + } + if (Fortran::lower::pft::Evaluation *alternateEntryEval = funit.getEntryEval()) genFIRBranch(alternateEntryEval->lexicalSuccessor->block); @@ -3217,10 +3226,10 @@ const Fortran::evaluate::IntrinsicProcTable &intrinsics, const Fortran::evaluate::TargetCharacteristics &targetCharacteristics, const Fortran::parser::AllCookedSources &cooked, llvm::StringRef triple, - fir::KindMapping &kindMap) + fir::KindMapping &kindMap, Fortran::runtime::Convert conversion) : defaultKinds{defaultKinds}, intrinsics{intrinsics}, targetCharacteristics{targetCharacteristics}, cooked{&cooked}, - context{context}, kindMap{kindMap} { + context{context}, kindMap{kindMap}, conversion{conversion} { // Register the diagnostic handler. context.getDiagEngine().registerHandler([](mlir::Diagnostic &diag) { llvm::raw_ostream &os = llvm::errs(); Index: flang/lib/Frontend/FrontendActions.cpp =================================================================== --- flang/lib/Frontend/FrontendActions.cpp +++ flang/lib/Frontend/FrontendActions.cpp @@ -148,7 +148,7 @@ *mlirCtx, defKinds, ci.getInvocation().getSemanticsContext().intrinsics(), ci.getInvocation().getSemanticsContext().targetCharacteristics(), ci.getParsing().allCooked(), ci.getInvocation().getTargetOpts().triple, - kindMap); + kindMap, ci.getInvocation().getFrontendOpts().conversion); // Create a parse tree and lower it to FIR Fortran::parser::Program &parseTree{*ci.getParsing().parseTree()}; Index: flang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- flang/lib/Frontend/CompilerInvocation.cpp +++ flang/lib/Frontend/CompilerInvocation.cpp @@ -15,6 +15,7 @@ #include "flang/Frontend/CodeGenOptions.h" #include "flang/Frontend/PreprocessorOptions.h" #include "flang/Frontend/TargetOptions.h" +#include "flang/Runtime/convert.h" #include "flang/Semantics/semantics.h" #include "flang/Version.inc" #include "clang/Basic/AllDiagnostics.h" @@ -366,6 +367,27 @@ } } + // Set conversion based on -fconvert=<value> + if (const auto *arg = + args.getLastArg(clang::driver::options::OPT_fconvert_EQ)) { + auto parseConvert = [](const char *s) { + return llvm::StringSwitch<std::optional<Fortran::runtime::Convert>>(s) + .Case("unknown", Fortran::runtime::Convert::Unknown) + .Case("native", Fortran::runtime::Convert::Native) + .Case("little-endian", Fortran::runtime::Convert::LittleEndian) + .Case("big-endian", Fortran::runtime::Convert::BigEndian) + .Case("swap", Fortran::runtime::Convert::Swap) + .Default(std::nullopt); + }; + + const char *argValue = arg->getValue(); + if (auto convert = parseConvert(argValue)) + opts.conversion = *convert; + else + diags.Report(clang::diag::err_drv_invalid_value) + << arg->getAsString(args) << argValue; + } + // -f{no-}implicit-none opts.features.Enable( Fortran::common::LanguageFeature::ImplicitNoneTypeAlways, Index: flang/include/flang/Runtime/main.h =================================================================== --- flang/include/flang/Runtime/main.h +++ flang/include/flang/Runtime/main.h @@ -15,6 +15,7 @@ FORTRAN_EXTERN_C_BEGIN void RTNAME(ProgramStart)(int, const char *[], const char *[]); void RTNAME(ByteswapOption)(void); // -byteswapio +void RTNAME(ConvertOption)(int); // -fconvert FORTRAN_EXTERN_C_END #endif // FORTRAN_RUNTIME_MAIN_H_ Index: flang/include/flang/Runtime/convert.h =================================================================== --- /dev/null +++ flang/include/flang/Runtime/convert.h @@ -0,0 +1,18 @@ +//===-- Runtime/convert.h ---------------------------------------*- 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_RUNTIME_RAGGED_H_ +#define FORTRAN_RUNTIME_RAGGED_H_ + +namespace Fortran::runtime { + +// External unformatted I/O data conversions +enum class Convert { Unknown, Native, LittleEndian, BigEndian, Swap }; + +} // namespace Fortran::runtime +#endif // FORTRAN_RUNTIME_RAGGED_H_ Index: flang/include/flang/Optimizer/Builder/Runtime/Convert.h =================================================================== --- /dev/null +++ flang/include/flang/Optimizer/Builder/Runtime/Convert.h @@ -0,0 +1,32 @@ +//===-- Convert.h -----------------------------------------------*- 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_CONVERT_H +#define FORTRAN_OPTIMIZER_BUILDER_RUNTIME_CONVERT_H + +namespace mlir { +class Location; +} // namespace mlir + +namespace fir { +class FirOpBuilder; +} // namespace fir + +namespace Fortran::runtime { +enum class Convert; +} // namespace Fortran::runtime + +namespace fir::runtime { + +/// Generate a call to the runtime routine to set the endian conversion for +/// unformatted files to the mode specified by \p conversion. +void genConvertOption(mlir::Location loc, fir::FirOpBuilder &builder, + Fortran::runtime::Convert conversion); + +} // namespace fir::runtime +#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_CONVERT_H Index: flang/include/flang/Lower/Bridge.h =================================================================== --- flang/include/flang/Lower/Bridge.h +++ flang/include/flang/Lower/Bridge.h @@ -34,6 +34,9 @@ namespace semantics { class SemanticsContext; } // namespace semantics +namespace runtime { +enum class Convert; +} // namespace runtime namespace lower { @@ -52,9 +55,10 @@ const Fortran::evaluate::IntrinsicProcTable &intrinsics, const Fortran::evaluate::TargetCharacteristics &targetCharacteristics, const Fortran::parser::AllCookedSources &allCooked, - llvm::StringRef triple, fir::KindMapping &kindMap) { + llvm::StringRef triple, fir::KindMapping &kindMap, + Fortran::runtime::Convert conversion) { return LoweringBridge(ctx, defaultKinds, intrinsics, targetCharacteristics, - allCooked, triple, kindMap); + allCooked, triple, kindMap, conversion); } //===--------------------------------------------------------------------===// @@ -83,6 +87,8 @@ /// Get the kind map. const fir::KindMapping &getKindMap() const { return kindMap; } + Fortran::runtime::Convert getConversion() const { return conversion; } + /// Create a folding context. Careful: this is very expensive. Fortran::evaluate::FoldingContext createFoldingContext() const; @@ -107,7 +113,7 @@ const Fortran::evaluate::IntrinsicProcTable &intrinsics, const Fortran::evaluate::TargetCharacteristics &targetCharacteristics, const Fortran::parser::AllCookedSources &cooked, llvm::StringRef triple, - fir::KindMapping &kindMap); + fir::KindMapping &kindMap, Fortran::runtime::Convert conversion); LoweringBridge() = delete; LoweringBridge(const LoweringBridge &) = delete; @@ -118,6 +124,7 @@ mlir::MLIRContext &context; std::unique_ptr<mlir::ModuleOp> module; fir::KindMapping &kindMap; + const Fortran::runtime::Convert conversion; }; } // namespace lower Index: flang/include/flang/Frontend/FrontendOptions.h =================================================================== --- flang/include/flang/Frontend/FrontendOptions.h +++ flang/include/flang/Frontend/FrontendOptions.h @@ -16,6 +16,7 @@ #include "flang/Common/Fortran-features.h" #include "flang/Parser/characters.h" #include "flang/Parser/unparse.h" +#include "flang/Runtime/convert.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/MemoryBuffer.h" #include <cstdint> @@ -258,6 +259,9 @@ // The form to process files in, if specified. FortranForm fortranForm = FortranForm::Unknown; + // Conversion to apply to unformatted IO, if specified. + Fortran::runtime::Convert conversion = Fortran::runtime::Convert::Unknown; + // The column after which characters are ignored in fixed form lines in the // source file. int fixedFormColumns = 72; Index: clang/lib/Driver/ToolChains/Flang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Flang.cpp +++ clang/lib/Driver/ToolChains/Flang.cpp @@ -29,19 +29,27 @@ void Flang::AddFortranDialectOptions(const ArgList &Args, ArgStringList &CmdArgs) const { - Args.AddAllArgs( - CmdArgs, {options::OPT_ffixed_form, options::OPT_ffree_form, - options::OPT_ffixed_line_length_EQ, options::OPT_fopenmp, - options::OPT_fopenacc, options::OPT_finput_charset_EQ, - options::OPT_fimplicit_none, options::OPT_fno_implicit_none, - options::OPT_fbackslash, options::OPT_fno_backslash, - options::OPT_flogical_abbreviations, - options::OPT_fno_logical_abbreviations, - options::OPT_fxor_operator, options::OPT_fno_xor_operator, - options::OPT_falternative_parameter_statement, - options::OPT_fdefault_real_8, options::OPT_fdefault_integer_8, - options::OPT_fdefault_double_8, options::OPT_flarge_sizes, - options::OPT_fno_automatic}); + Args.AddAllArgs(CmdArgs, {options::OPT_ffixed_form, + options::OPT_ffree_form, + options::OPT_ffixed_line_length_EQ, + options::OPT_fopenmp, + options::OPT_fopenacc, + options::OPT_finput_charset_EQ, + options::OPT_fimplicit_none, + options::OPT_fno_implicit_none, + options::OPT_fbackslash, + options::OPT_fno_backslash, + options::OPT_flogical_abbreviations, + options::OPT_fno_logical_abbreviations, + options::OPT_fxor_operator, + options::OPT_fno_xor_operator, + options::OPT_falternative_parameter_statement, + options::OPT_fdefault_real_8, + options::OPT_fdefault_integer_8, + options::OPT_fdefault_double_8, + options::OPT_flarge_sizes, + options::OPT_fno_automatic, + options::OPT_fconvert_EQ}); } void Flang::AddPreprocessingOptions(const ArgList &Args, Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -4794,7 +4794,6 @@ def fblas_matmul_limit_EQ : Joined<["-"], "fblas-matmul-limit=">, Group<gfortran_Group>; 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 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>; @@ -4895,6 +4894,8 @@ DocBrief<[{Set column after which characters are ignored in typical fixed-form lines in the source file}]>; def ffixed_line_length_VALUE : Joined<["-"], "ffixed-line-length-">, Group<f_Group>, Alias<ffixed_line_length_EQ>; +def fconvert_EQ : Joined<["-"], "fconvert=">, Group<f_Group>, + HelpText<"Set endian conversion of data for unformatted files">; def fopenacc : Flag<["-"], "fopenacc">, Group<f_Group>, HelpText<"Enable OpenACC">; def fdefault_double_8 : Flag<["-"],"fdefault-double-8">, Group<f_Group>,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits