jpenix-quic updated this revision to Diff 447838.
jpenix-quic added a comment.

Added changes to address feedback about missing braces and where I am adding 
options::OPT_fconvert_EQ (and removing the extra formatting change). Also 
removes an unnecessary include I had mistakenly added.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D130513/new/

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,20 @@
         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,7 @@
 #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/Ragged.h"
 #include "flang/Optimizer/Builder/Todo.h"
 #include "flang/Optimizer/Dialect/FIRAttr.h"
@@ -41,6 +42,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 +2754,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 +3225,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
@@ -55,7 +55,8 @@
   Args.AddAllArgs(CmdArgs,
                   {options::OPT_module_dir, options::OPT_fdebug_module_writer,
                    options::OPT_fintrinsic_modules_path, options::OPT_pedantic,
-                   options::OPT_std_EQ, options::OPT_W_Joined});
+                   options::OPT_std_EQ, options::OPT_W_Joined,
+                   options::OPT_fconvert_EQ});
 }
 
 void Flang::ConstructJob(Compilation &C, const JobAction &JA,
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

Reply via email to