//===-- tools/f18/f18.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
//
//===----------------------------------------------------------------------===//

// Temporary Fortran front end driver main program for development scaffolding.

#include "flang/Common/Fortran-features.h"
#include "flang/Common/default-kinds.h"
#include "flang/Evaluate/expression.h"
#include "flang/Lower/PFTBuilder.h"
#include "flang/Parser/characters.h"
#include "flang/Parser/dump-parse-tree.h"
#include "flang/Parser/message.h"
#include "flang/Parser/parse-tree-visitor.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Parser/parsing.h"
#include "flang/Parser/provenance.h"
#include "flang/Parser/unparse.h"
#include "flang/Semantics/expression.h"
#include "flang/Semantics/runtime-type-info.h"
#include "flang/Semantics/semantics.h"
#include "flang/Semantics/unparse-with-symbols.h"
#include "flang/Version.inc"
#include "llvm/Support/Errno.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdio>
#include <cstring>
#include <fstream>
#include <list>
#include <memory>
#include <optional>
#include <stdlib.h>
#include <string>
#include <vector>

static std::list<std::string> argList(int argc, char *const argv[]) {
  std::list<std::string> result;
  for (int j = 0; j < argc; ++j) {
    result.emplace_back(argv[j]);
  }
  return result;
}

struct MeasurementVisitor {
  template <typename A> bool Pre(const A &) { return true; }
  template <typename A> void Post(const A &) {
    ++objects;
    bytes += sizeof(A);
  }
  size_t objects{0}, bytes{0};
};

void MeasureParseTree(const Fortran::parser::Program &program) {
  MeasurementVisitor visitor;
  Fortran::parser::Walk(program, visitor);
  llvm::outs() << "Parse tree comprises " << visitor.objects
               << " objects and occupies " << visitor.bytes
               << " total bytes.\n";
}

std::vector<std::string> filesToDelete;

void CleanUpAtExit() {
  for (const auto &path : filesToDelete) {
    if (!path.empty()) {
      llvm::sys::fs::remove(path);
    }
  }
}

struct GetDefinitionArgs {
  int line, startColumn, endColumn;
};

struct DriverOptions {
  DriverOptions() {}
  bool verbose{false}; // -v
  bool compileOnly{false}; // -c
  std::string outputPath; // -o path
  std::vector<std::string> searchDirectories; // -I dir
  std::string moduleDirectory{"."s}; // -module dir
  std::string moduleFileSuffix{".mod"}; // -moduleSuffix suff
  bool forcedForm{false}; // -Mfixed or -Mfree appeared
  bool warnOnNonstandardUsage{false}; // -Mstandard
  bool warningsAreErrors{false}; // -Werror
  bool byteswapio{false}; // -byteswapio
  Fortran::parser::Encoding encoding{Fortran::parser::Encoding::UTF_8};
  bool syntaxOnly{false};
  bool dumpProvenance{false};
  bool dumpCookedChars{false};
  bool dumpUnparse{false};
  bool dumpUnparseWithSymbols{false};
  bool dumpParseTree{false};
  bool dumpPreFirTree{false};
  bool dumpSymbols{false};
  bool debugNoSemantics{false};
  bool debugModuleWriter{false};
  bool defaultReal8{false};
  bool measureTree{false};
  bool unparseTypedExprsToF18_FC{false};
  std::vector<std::string> F18_FCArgs;
  const char *prefix{nullptr};
  bool getDefinition{false};
  GetDefinitionArgs getDefinitionArgs{0, 0, 0};
  bool getSymbolsSources{false};
  std::optional<bool> forcePreprocessing; // -cpp & -nocpp
};

void Exec(std::vector<llvm::StringRef> &argv, bool verbose = false) {
  if (verbose) {
    for (size_t j{0}; j < argv.size(); ++j) {
      llvm::errs() << (j > 0 ? " " : "") << argv[j];
    }
    llvm::errs() << '\n';
  }
  std::string ErrMsg;
  llvm::ErrorOr<std::string> Program = llvm::sys::findProgramByName(argv[0]);
  if (!Program)
    ErrMsg = Program.getError().message();
  if (!Program ||
      llvm::sys::ExecuteAndWait(
          Program.get(), argv, llvm::None, {}, 0, 0, &ErrMsg)) {
    llvm::errs() << "execvp(" << argv[0] << ") failed: " << ErrMsg << '\n';
    exit(EXIT_FAILURE);
  }
}

void RunOtherCompiler(DriverOptions &driver, char *source, char *relo) {
  std::vector<llvm::StringRef> argv;
  for (size_t j{0}; j < driver.F18_FCArgs.size(); ++j) {
    argv.push_back(driver.F18_FCArgs[j]);
  }
  char dashC[3] = "-c", dashO[3] = "-o";
  argv.push_back(dashC);
  argv.push_back(dashO);
  argv.push_back(relo);
  argv.push_back(source);
  Exec(argv, driver.verbose);
}

std::string RelocatableName(const DriverOptions &driver, std::string path) {
  if (driver.compileOnly && !driver.outputPath.empty()) {
    return driver.outputPath;
  }
  std::string base{path};
  auto slash{base.rfind("/")};
  if (slash != std::string::npos) {
    base = base.substr(slash + 1);
  }
  std::string relo{base};
  auto dot{base.rfind(".")};
  if (dot != std::string::npos) {
    relo = base.substr(0, dot);
  }
  relo += ".o";
  return relo;
}

int exitStatus{EXIT_SUCCESS};

static Fortran::parser::AnalyzedObjectsAsFortran asFortran{
    [](llvm::raw_ostream &o, const Fortran::evaluate::GenericExprWrapper &x) {
      if (x.v) {
        x.v->AsFortran(o);
      } else {
        o << "(bad expression)";
      }
    },
    [](llvm::raw_ostream &o,
        const Fortran::evaluate::GenericAssignmentWrapper &x) {
      if (x.v) {
        x.v->AsFortran(o);
      } else {
        o << "(bad assignment)";
      }
    },
    [](llvm::raw_ostream &o, const Fortran::evaluate::ProcedureRef &x) {
      x.AsFortran(o << "CALL ");
    },
};

std::string CompileFortran(std::string path, Fortran::parser::Options options,
    DriverOptions &driver,
    const Fortran::common::IntrinsicTypeDefaultKinds &defaultKinds) {
  Fortran::parser::AllSources allSources;
  Fortran::parser::AllCookedSources allCookedSources{allSources};
  allSources.set_encoding(driver.encoding);
  Fortran::semantics::SemanticsContext semanticsContext{
      defaultKinds, options.features, allCookedSources};
  semanticsContext.set_moduleDirectory(driver.moduleDirectory)
      .set_moduleFileSuffix(driver.moduleFileSuffix)
      .set_searchDirectories(driver.searchDirectories)
      .set_warnOnNonstandardUsage(driver.warnOnNonstandardUsage)
      .set_warningsAreErrors(driver.warningsAreErrors);
  if (!driver.forcedForm) {
    auto dot{path.rfind(".")};
    if (dot != std::string::npos) {
      std::string suffix{path.substr(dot + 1)};
      options.isFixedForm = suffix == "f" || suffix == "F" || suffix == "ff";
    }
  }
  options.searchDirectories = driver.searchDirectories;
  Fortran::parser::Parsing parsing{allCookedSources};
  parsing.Prescan(path, options);
  if (!parsing.messages().empty() &&
      (driver.warningsAreErrors || parsing.messages().AnyFatalError())) {
    llvm::errs() << driver.prefix << "Could not scan " << path << '\n';
    parsing.messages().Emit(llvm::errs(), allCookedSources);
    exitStatus = EXIT_FAILURE;
    return {};
  }
  if (driver.dumpProvenance) {
    parsing.DumpProvenance(llvm::outs());
    return {};
  }
  if (driver.dumpCookedChars) {
    parsing.messages().Emit(llvm::errs(), allCookedSources);
    parsing.DumpCookedChars(llvm::outs());
    return {};
  }
  parsing.Parse(llvm::outs());
  if (options.instrumentedParse) {
    parsing.DumpParsingLog(llvm::outs());
    return {};
  }
  parsing.ClearLog();
  parsing.messages().Emit(llvm::errs(), allCookedSources);
  if (!parsing.consumedWholeFile()) {
    parsing.EmitMessage(llvm::errs(), parsing.finalRestingPlace(),
        "Parser FAIL (final position)");
    exitStatus = EXIT_FAILURE;
    return {};
  }
  if ((!parsing.messages().empty() &&
          (driver.warningsAreErrors || parsing.messages().AnyFatalError())) ||
      !parsing.parseTree()) {
    llvm::errs() << driver.prefix << "Could not parse " << path << '\n';
    exitStatus = EXIT_FAILURE;
    return {};
  }
  auto &parseTree{*parsing.parseTree()};
  if (driver.measureTree) {
    MeasureParseTree(parseTree);
  }
  if (!driver.debugNoSemantics || driver.dumpSymbols ||
      driver.dumpUnparseWithSymbols || driver.getDefinition ||
      driver.getSymbolsSources) {
    Fortran::semantics::Semantics semantics{semanticsContext, parseTree,
        parsing.cooked().AsCharBlock(), driver.debugModuleWriter};
    semantics.Perform();
    semantics.EmitMessages(llvm::errs());
    if (semantics.AnyFatalError()) {
      if (driver.dumpSymbols) {
        semantics.DumpSymbols(llvm::outs());
      }
      llvm::errs() << driver.prefix << "Semantic errors in " << path << '\n';
      exitStatus = EXIT_FAILURE;
      if (driver.dumpParseTree) {
        Fortran::parser::DumpTree(llvm::outs(), parseTree, &asFortran);
      }
      return {};
    }
    auto tables{
        Fortran::semantics::BuildRuntimeDerivedTypeTables(semanticsContext)};
    if (!tables.schemata) {
      llvm::errs() << driver.prefix
                   << "could not find module file for __fortran_type_info\n";
    }
    if (driver.dumpSymbols) {
      semantics.DumpSymbols(llvm::outs());
    }
    if (driver.dumpUnparseWithSymbols) {
      Fortran::semantics::UnparseWithSymbols(
          llvm::outs(), parseTree, driver.encoding);
      return {};
    }
    if (driver.getSymbolsSources) {
      semantics.DumpSymbolsSources(llvm::outs());
      return {};
    }
    if (driver.getDefinition) {
      if (auto cb{allCookedSources.GetCharBlockFromLineAndColumns(
              driver.getDefinitionArgs.line,
              driver.getDefinitionArgs.startColumn,
              driver.getDefinitionArgs.endColumn)}) {
        llvm::errs() << "String range: >" << cb->ToString() << "<\n";
        if (auto symbol{semanticsContext.FindScope(*cb).FindSymbol(*cb)}) {
          llvm::errs() << "Found symbol name: " << symbol->name().ToString()
                       << "\n";
          if (auto sourceInfo{
                  allCookedSources.GetSourcePositionRange(symbol->name())}) {
            llvm::outs() << symbol->name().ToString() << ": "
                         << sourceInfo->first.file.path() << ", "
                         << sourceInfo->first.line << ", "
                         << sourceInfo->first.column << "-"
                         << sourceInfo->second.column << "\n";
            exitStatus = EXIT_SUCCESS;
            return {};
          }
        }
      }
      llvm::errs() << "Symbol not found.\n";
      exitStatus = EXIT_FAILURE;
      return {};
    }
  }
  if (driver.dumpParseTree) {
    Fortran::parser::DumpTree(llvm::outs(), parseTree, &asFortran);
  }
  if (driver.dumpUnparse) {
    Unparse(llvm::outs(), parseTree, driver.encoding, true /*capitalize*/,
        options.features.IsEnabled(
            Fortran::common::LanguageFeature::BackslashEscapes),
        nullptr /* action before each statement */, &asFortran);
    return {};
  }
  if (driver.dumpPreFirTree) {
    if (auto ast{Fortran::lower::createPFT(parseTree, semanticsContext)}) {
      Fortran::lower::dumpPFT(llvm::outs(), *ast);
    } else {
      llvm::errs() << "Pre FIR Tree is NULL.\n";
      exitStatus = EXIT_FAILURE;
    }
  }
  if (driver.syntaxOnly) {
    return {};
  }

  std::string relo{RelocatableName(driver, path)};

  llvm::SmallString<32> tmpSourcePath;
  {
    int fd;
    std::error_code EC =
        llvm::sys::fs::createUniqueFile("f18-%%%%.f90", fd, tmpSourcePath);
    if (EC) {
      llvm::errs() << EC.message() << "\n";
      std::exit(EXIT_FAILURE);
    }
    llvm::raw_fd_ostream tmpSource(fd, /*shouldClose*/ true);
    Unparse(tmpSource, parseTree, driver.encoding, true /*capitalize*/,
        options.features.IsEnabled(
            Fortran::common::LanguageFeature::BackslashEscapes),
        nullptr /* action before each statement */,
        driver.unparseTypedExprsToF18_FC ? &asFortran : nullptr);
  }

  RunOtherCompiler(driver, tmpSourcePath.data(), relo.data());
  filesToDelete.emplace_back(tmpSourcePath);
  if (!driver.compileOnly && driver.outputPath.empty()) {
    filesToDelete.push_back(relo);
  }
  return relo;
}

std::string CompileOtherLanguage(std::string path, DriverOptions &driver) {
  std::string relo{RelocatableName(driver, path)};
  RunOtherCompiler(driver, path.data(), relo.data());
  if (!driver.compileOnly && driver.outputPath.empty()) {
    filesToDelete.push_back(relo);
  }
  return relo;
}

void Link(std::vector<std::string> &liblist, std::vector<std::string> &objects,
    DriverOptions &driver) {
  std::vector<llvm::StringRef> argv;
  for (size_t j{0}; j < driver.F18_FCArgs.size(); ++j) {
    argv.push_back(driver.F18_FCArgs[j].data());
  }
  for (auto &obj : objects) {
    argv.push_back(obj.data());
  }
  if (!driver.outputPath.empty()) {
    char dashO[3] = "-o";
    argv.push_back(dashO);
    argv.push_back(driver.outputPath.data());
  }
  for (auto &lib : liblist) {
    argv.push_back(lib.data());
  }
  Exec(argv, driver.verbose);
}

int printVersion() {
  llvm::errs() << "\nf18 compiler (under development), version "
               << FLANG_VERSION_STRING << "\n";
  return exitStatus;
}

// Generate the path to look for intrinsic modules
static std::string getIntrinsicDir() {
  // TODO: Find a system independent API
  llvm::SmallString<128> driverPath;
  driverPath.assign(llvm::sys::fs::getMainExecutable(nullptr, nullptr));
  llvm::sys::path::remove_filename(driverPath);
  driverPath.append("/../include/flang/");
  return std::string(driverPath);
}

int main(int argc, char *const argv[]) {

  atexit(CleanUpAtExit);

  DriverOptions driver;
  const char *F18_FC{getenv("F18_FC")};
  driver.F18_FCArgs.push_back(F18_FC ? F18_FC : "gfortran");
  bool isPGF90{driver.F18_FCArgs.back().rfind("pgf90") != std::string::npos};

  std::list<std::string> args{argList(argc, argv)};
  std::vector<std::string> objlist, liblist;
  std::string prefix{args.front()};
  args.pop_front();
  prefix += ": ";
  driver.prefix = prefix.data();

  Fortran::parser::Options options;
  std::vector<Fortran::parser::Options::Predefinition> predefinitions;
  predefinitions.emplace_back("__F18", "1");
  predefinitions.emplace_back("__F18_MAJOR__", "1");
  predefinitions.emplace_back("__F18_MINOR__", "1");
  predefinitions.emplace_back("__F18_PATCHLEVEL__", "1");
  predefinitions.emplace_back("__flang__", FLANG_VERSION_STRING);
  predefinitions.emplace_back("__flang_major__", FLANG_VERSION_MAJOR_STRING);
  predefinitions.emplace_back("__flang_minor__", FLANG_VERSION_MINOR_STRING);
  predefinitions.emplace_back(
      "__flang_patchlevel__", FLANG_VERSION_PATCHLEVEL_STRING);
#if __x86_64__
  predefinitions.emplace_back("__x86_64__", "1");
#endif

  Fortran::common::IntrinsicTypeDefaultKinds defaultKinds;

  std::vector<std::string> fortranSources, otherSources;
  bool anyFiles{false};

  // Add the default intrinsic module directory to the list of search
  // directories
  driver.searchDirectories.push_back(getIntrinsicDir());

  while (!args.empty()) {
    std::string arg{std::move(args.front())};
    auto dot{arg.rfind(".")};
    std::string suffix{arg.substr(dot + 1)};
    std::string prefix{arg.substr(0, 2)};
    args.pop_front();
    if (arg.empty()) {
    } else if (arg.at(0) != '-') {
      anyFiles = true;
      if (dot == std::string::npos) {
        driver.F18_FCArgs.push_back(arg);
      } else {
        if (suffix == "f" || suffix == "F" || suffix == "ff" ||
            suffix == "f90" || suffix == "F90" || suffix == "ff90" ||
            suffix == "f95" || suffix == "F95" || suffix == "ff95" ||
            suffix == "cuf" || suffix == "CUF" || suffix == "f18" ||
            suffix == "F18" || suffix == "ff18") {
          fortranSources.push_back(arg);
        } else if (suffix == "o" || suffix == "so") {
          objlist.push_back(arg);
        } else if (suffix == "a") {
          liblist.push_back(arg);
        } else {
          otherSources.push_back(arg);
        }
      }
    } else if (prefix == "-l" || suffix == "a") {
      liblist.push_back(arg);
    } else if (arg == "-") {
      fortranSources.push_back("-");
    } else if (arg == "--") {
      while (!args.empty()) {
        fortranSources.emplace_back(std::move(args.front()));
        args.pop_front();
      }
      break;
    } else if (arg == "-Mfixed" || arg == "-ffixed-form") {
      driver.forcedForm = true;
      options.isFixedForm = true;
    } else if (arg == "-Mfree" || arg == "-ffree-form") {
      driver.forcedForm = true;
      options.isFixedForm = false;
    } else if (arg == "-Mextend" || arg == "-ffixed-line-length-132") {
      options.fixedFormColumns = 132;
    } else if (arg == "-Munlimited" || arg == "-ffree-line-length-none" ||
        arg == "-ffree-line-length-0" || arg == "-ffixed-line-length-none" ||
        arg == "-ffixed-line-length-0") {
      // For reparsing f18's -E output of fixed-form cooked character stream
      options.fixedFormColumns = 1000000;
    } else if (arg == "-Mbackslash") {
      options.features.Enable(
          Fortran::common::LanguageFeature::BackslashEscapes, false);
    } else if (arg == "-Mnobackslash") {
      options.features.Enable(
          Fortran::common::LanguageFeature::BackslashEscapes, true);
    } else if (arg == "-Mstandard" || arg == "-std=f95" ||
        arg == "-std=f2003" || arg == "-std=f2008" || arg == "-std=legacy" ||
        arg == "-std=f2018" || arg == "-pedantic") {
      driver.warnOnNonstandardUsage = true;
    } else if (arg == "-fopenacc") {
      options.features.Enable(Fortran::common::LanguageFeature::OpenACC);
      predefinitions.emplace_back("_OPENACC", "202011");
    } else if (arg == "-fopenmp") {
      options.features.Enable(Fortran::common::LanguageFeature::OpenMP);
      predefinitions.emplace_back("_OPENMP", "201511");
    } else if (arg.find("-W") != std::string::npos) {
      if (arg == "-Werror")
        driver.warningsAreErrors = true;
      else {
        // Only -Werror is supported currently
        llvm::errs() << "Only `-Werror` is supported currently.\n";
        return EXIT_FAILURE;
      }
    } else if (arg == "-ed") {
      options.features.Enable(Fortran::common::LanguageFeature::OldDebugLines);
    } else if (arg == "-E") {
      driver.dumpCookedChars = true;
    } else if (arg == "-fbackslash" || arg == "-fno-backslash") {
      options.features.Enable(
          Fortran::common::LanguageFeature::BackslashEscapes,
          arg == "-fbackslash");
    } else if (arg == "-fxor-operator" || arg == "-fno-xor-operator") {
      options.features.Enable(Fortran::common::LanguageFeature::XOROperator,
          arg == "-fxor-operator");
    } else if (arg == "-flogical-abbreviations" ||
        arg == "-fno-logical-abbreviations") {
      options.features.Enable(
          Fortran::parser::LanguageFeature::LogicalAbbreviations,
          arg == "-flogical-abbreviations");
    } else if (arg == "-fimplicit-none-type-always" ||
        arg == "-fimplicit-none") {
      options.features.Enable(
          Fortran::common::LanguageFeature::ImplicitNoneTypeAlways);
    } else if (arg == "-fno-implicit-none") {
      options.features.Enable(
          Fortran::common::LanguageFeature::ImplicitNoneTypeAlways, false);
    } else if (arg == "-fimplicit-none-type-never") {
      options.features.Enable(
          Fortran::common::LanguageFeature::ImplicitNoneTypeNever);
    } else if (arg == "-falternative-parameter-statement") {
      options.features.Enable(
          Fortran::common::LanguageFeature::OldStyleParameter, true);
    } else if (arg == "-fdebug-dump-provenance") {
      driver.dumpProvenance = true;
      options.needProvenanceRangeToCharBlockMappings = true;
    } else if (arg == "-fdebug-dump-parse-tree") {
      driver.dumpParseTree = true;
      driver.syntaxOnly = true;
    } else if (arg == "-fdebug-pre-fir-tree") {
      driver.dumpPreFirTree = true;
    } else if (arg == "-fdebug-dump-symbols") {
      driver.dumpSymbols = true;
      driver.syntaxOnly = true;
    } else if (arg == "-fdebug-module-writer") {
      driver.debugModuleWriter = true;
    } else if (arg == "-fdebug-measure-parse-tree") {
      driver.measureTree = true;
    } else if (arg == "-fdebug-instrumented-parse" ||
        arg == "-fdebug-dump-parsing-log") {
      options.instrumentedParse = true;
    } else if (arg == "-fdebug-no-semantics") {
      driver.debugNoSemantics = true;
    } else if (arg == "-fdebug-unparse-no-sema") {
      driver.debugNoSemantics = true;
      driver.dumpUnparse = true;
    } else if (arg == "-fdebug-dump-parse-tree-no-sema") {
      driver.debugNoSemantics = true;
      driver.dumpParseTree = true;
      driver.syntaxOnly = true;
    } else if (arg == "-funparse" || arg == "-fdebug-unparse") {
      driver.dumpUnparse = true;
    } else if (arg == "-funparse-with-symbols" ||
        arg == "-fdebug-unparse-with-symbols") {
      driver.dumpUnparseWithSymbols = true;
    } else if (arg == "-funparse-typed-exprs-to-f18-fc") {
      driver.unparseTypedExprsToF18_FC = true;
    } else if (arg == "-fparse-only" || arg == "-fsyntax-only") {
      driver.syntaxOnly = true;
    } else if (arg == "-c") {
      driver.compileOnly = true;
    } else if (arg == "-o") {
      driver.outputPath = args.front();
      args.pop_front();
    } else if (arg.substr(0, 2) == "-D") {
      auto eq{arg.find('=')};
      if (eq == std::string::npos) {
        predefinitions.emplace_back(arg.substr(2), "1");
      } else {
        predefinitions.emplace_back(arg.substr(2, eq - 2), arg.substr(eq + 1));
      }
    } else if (arg.substr(0, 2) == "-U") {
      predefinitions.emplace_back(arg.substr(2), std::optional<std::string>{});
    } else if (arg == "-r8" || arg == "-fdefault-real-8") {
      driver.defaultReal8 = true;
      defaultKinds.set_defaultRealKind(8);
      defaultKinds.set_doublePrecisionKind(16);
    } else if (arg == "-fdefault-double-8") {
      if (!driver.defaultReal8) {
        // -fdefault-double-8 has to be used with -fdefault-real-8
        // to be compatible with gfortran. See:
        // https://gcc.gnu.org/onlinedocs/gfortran/Fortran-Dialect-Options.html
        llvm::errs()
            << "Use of `-fdefault-double-8` requires `-fdefault-real-8`\n";
        return EXIT_FAILURE;
      }
      defaultKinds.set_doublePrecisionKind(8);
    } else if (arg == "-i8" || arg == "-fdefault-integer-8") {
      defaultKinds.set_defaultIntegerKind(8);
      defaultKinds.set_subscriptIntegerKind(8);
      defaultKinds.set_sizeIntegerKind(8);
      if (isPGF90) {
        driver.F18_FCArgs.push_back("-i8");
      } else {
        driver.F18_FCArgs.push_back("-fdefault-integer-8");
      }
    } else if (arg == "-flarge-sizes") {
      defaultKinds.set_sizeIntegerKind(8);
    } else if (arg == "-fno-large-sizes") {
      defaultKinds.set_sizeIntegerKind(4);
    } else if (arg == "-module") {
      driver.moduleDirectory = args.front();
      args.pop_front();
    } else if (arg == "-module-dir") {
      driver.moduleDirectory = args.front();
      driver.searchDirectories.push_back(driver.moduleDirectory);
      args.pop_front();
    } else if (arg == "-module-suffix") {
      driver.moduleFileSuffix = args.front();
      args.pop_front();
    } else if (arg == "-intrinsic-module-directory" ||
        arg == "-fintrinsic-modules-path") {
      // prepend to the list of search directories
      driver.searchDirectories.insert(
          driver.searchDirectories.begin(), args.front());
      args.pop_front();
    } else if (arg == "-futf-8") {
      driver.encoding = Fortran::parser::Encoding::UTF_8;
    } else if (arg == "-flatin") {
      driver.encoding = Fortran::parser::Encoding::LATIN_1;
    } else if (arg == "-fget-definition") {
      // Receives 3 arguments: line, startColumn, endColumn.
      options.needProvenanceRangeToCharBlockMappings = true;
      driver.getDefinition = true;
      char *endptr;
      int arguments[3];
      for (int i = 0; i < 3; i++) {
        if (args.empty()) {
          llvm::errs() << "Must provide 3 arguments for -fget-definitions.\n";
          return EXIT_FAILURE;
        }
        arguments[i] = std::strtol(args.front().c_str(), &endptr, 10);
        if (*endptr != '\0') {
          llvm::errs() << "Invalid argument to -fget-definitions: "
                       << args.front() << '\n';
          return EXIT_FAILURE;
        }
        args.pop_front();
      }
      driver.getDefinitionArgs = {arguments[0], arguments[1], arguments[2]};
    } else if (arg == "-fget-symbols-sources") {
      driver.getSymbolsSources = true;
    } else if (arg == "-byteswapio") {
      driver.byteswapio = true; // TODO: Pass to lowering, generate call
    } else if (arg == "-cpp") {
      driver.forcePreprocessing = true;
    } else if (arg == "-nocpp") {
      driver.forcePreprocessing = false;
    } else if (arg == "-h" || arg == "-help" || arg == "--help" ||
        arg == "-?") {
      llvm::errs()
          << "f18: LLVM Fortran compiler\n"
          << "\n"
          << "Usage: f18 [options] <input files>\n"
          << "\n"
          << "Defaults:\n"
          << "  When invoked with input files, and no options to tell\n"
          << "  it otherwise, f18 will unparse its input and pass that on to "
             "an\n"
          << "  external compiler to continue the compilation.\n"
          << "  The external compiler is specified by the F18_FC environment\n"
          << "  variable. The default is 'gfortran'.\n"
          << "  If invoked with no input files, f18 reads source code from\n"
          << "  stdin and runs with -fdebug-measure-parse-tree -funparse.\n"
          << "\n"
          << "f18 options:\n"
          << "  -Mfixed | -Mfree | -ffixed-form | -ffree-form   force the "
             "source form\n"
          << "  -Mextend | -ffixed-line-length-132   132-column fixed form\n"
          << "  -f[no-]backslash     enable[disable] \\escapes in literals\n"
          << "  -M[no]backslash      disable[enable] \\escapes in literals\n"
          << "  -Mstandard           enable conformance warnings\n"
          << "  -std=<standard>      enable conformance warnings\n"
          << "  -r8 | -fdefault-real-8 | -i8 | -fdefault-integer-8 | "
             "-fdefault-double-8   change default kinds of intrinsic types\n"
          << "  -Werror              treat warnings as errors\n"
          << "  -ed                  enable fixed form D lines\n"
          << "  -E                   prescan & preprocess only\n"
          << "  -module dir          module output directory (default .)\n"
          << "  -module-dir/-J <dir> Put MODULE files in <dir>\n"
          << "  -flatin              interpret source as Latin-1 (ISO 8859-1) "
             "rather than UTF-8\n"
          << "  -fsyntax-only        parsing and semantics only, no output "
             "except messages\n"
          << "  -funparse            parse & reformat only, no code "
             "generation\n"
          << "  -funparse-with-symbols  parse, resolve symbols, and unparse\n"
          << "  -fdebug-measure-parse-tree\n"
          << "  -fdebug-dump-provenance\n"
          << "  -fdebug-dump-parse-tree\n"
          << "  -fdebug-dump-symbols\n"
          << "  -fdebug-instrumented-parse\n"
          << "  -fdebug-no-semantics  disable semantic checks\n"
          << "  -fget-definition\n"
          << "  -fget-symbols-sources\n"
          << "  -v -c -o -I -D -U    have their usual meanings\n"
          << "  -cpp / -nocpp        force / inhibit macro replacement\n"
          << "  -help                print this again\n"
          << "Unrecognised options are passed through to the external "
             "compiler\n"
          << "set by F18_FC (see defaults).\n";
      return exitStatus;
    } else if (arg == "-V" || arg == "--version") {
      return printVersion();
    } else if (arg == "-fdebug-stack-trace") {
      llvm::sys::PrintStackTraceOnErrorSignal(llvm::StringRef{}, true);
    } else {
      driver.F18_FCArgs.push_back(arg);
      if (arg == "-v") {
        if (args.size() > 1) {
          driver.verbose = true;
        } else {
          return printVersion();
        }
      } else if (arg == "-I") {
        driver.F18_FCArgs.push_back(args.front());
        driver.searchDirectories.push_back(args.front());
        args.pop_front();
      } else if (arg.substr(0, 2) == "-I") {
        driver.searchDirectories.push_back(arg.substr(2));
      } else if (arg == "-J") {
        driver.F18_FCArgs.push_back(args.front());
        driver.moduleDirectory = args.front();
        driver.searchDirectories.push_back(driver.moduleDirectory);
        args.pop_front();
      } else if (arg.substr(0, 2) == "-J") {
        driver.moduleDirectory = arg.substr(2);
        driver.searchDirectories.push_back(driver.moduleDirectory);
      }
    }
  }

  if (driver.warnOnNonstandardUsage) {
    options.features.WarnOnAllNonstandard();
  }
  if (isPGF90) {
    if (!options.features.IsEnabled(
            Fortran::common::LanguageFeature::BackslashEscapes)) {
      driver.F18_FCArgs.push_back(
          "-Mbackslash"); // yes, this *disables* them in pgf90
    }
    if (options.features.IsEnabled(Fortran::common::LanguageFeature::OpenMP)) {
      driver.F18_FCArgs.push_back("-mp");
    }

    Fortran::parser::useHexadecimalEscapeSequences = false;
  } else {
    if (options.features.IsEnabled(
            Fortran::common::LanguageFeature::BackslashEscapes)) {
      driver.F18_FCArgs.push_back("-fbackslash");
    }
    if (options.features.IsEnabled(Fortran::common::LanguageFeature::OpenMP)) {
      driver.F18_FCArgs.push_back("-fopenmp");
    }

    Fortran::parser::useHexadecimalEscapeSequences = true;
  }

  if (!anyFiles) {
    driver.measureTree = true;
    driver.dumpUnparse = true;
    llvm::outs() << "Enter Fortran source\n"
                 << "Use EOF character (^D) to end file\n";
    CompileFortran("-", options, driver, defaultKinds);
    return exitStatus;
  }
  for (const auto &path : fortranSources) {
    options.predefinitions.clear();
    if (driver.forcePreprocessing) {
      if (*driver.forcePreprocessing) {
        options.predefinitions = predefinitions;
      }
    } else {
      auto dot{path.rfind(".")};
      if (dot != std::string::npos) {
        std::string suffix{path.substr(dot + 1)};
        if (suffix == "F" || suffix == "F90" || suffix == "F95" ||
            suffix == "CUF" || suffix == "F18") {
          options.predefinitions = predefinitions;
        }
      }
    }
    std::string relo{CompileFortran(path, options, driver, defaultKinds)};
    if (!driver.compileOnly && !relo.empty()) {
      objlist.push_back(relo);
    }
  }
  for (const auto &path : otherSources) {
    std::string relo{CompileOtherLanguage(path, driver)};
    if (!driver.compileOnly && !relo.empty()) {
      objlist.push_back(relo);
    }
  }
  if (!driver.compileOnly && !objlist.empty()) {
    Link(liblist, objlist, driver);
  }
  return exitStatus;
}
