//===--- FrontendAction.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
//
//===----------------------------------------------------------------------===//
//
// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
//
//===----------------------------------------------------------------------===//

#include "flang/Frontend/FrontendAction.h"
#include "flang/Frontend/CompilerInstance.h"
#include "flang/Frontend/FrontendActions.h"
#include "flang/Frontend/FrontendOptions.h"
#include "flang/Frontend/FrontendPluginRegistry.h"
#include "clang/Basic/DiagnosticFrontend.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/VirtualFileSystem.h"

using namespace Fortran::frontend;

LLVM_INSTANTIATE_REGISTRY(FrontendPluginRegistry)

void FrontendAction::setCurrentInput(const FrontendInputFile &input) {
  this->currentInput = input;
}

// Call this method if BeginSourceFile fails.
// Deallocate compiler instance, input and output descriptors
static void beginSourceFileCleanUp(FrontendAction &fa, CompilerInstance &ci) {
  ci.clearOutputFiles(/*EraseFiles=*/true);
  fa.setCurrentInput(FrontendInputFile());
  fa.setInstance(nullptr);
}

bool FrontendAction::beginSourceFile(CompilerInstance &ci,
                                     const FrontendInputFile &realInput) {

  FrontendInputFile input(realInput);

  // Return immediately if the input file does not exist or is not a file. Note
  // that we cannot check this for input from stdin.
  if (input.getFile() != "-") {
    if (!llvm::sys::fs::is_regular_file(input.getFile())) {
      // Create an diagnostic ID to report
      unsigned diagID;
      if (llvm::vfs::getRealFileSystem()->exists(input.getFile())) {
        ci.getDiagnostics().Report(clang::diag::err_fe_error_reading)
            << input.getFile() << "not a regular file";
        diagID = ci.getDiagnostics().getCustomDiagID(
            clang::DiagnosticsEngine::Error, "%0 is not a regular file");
      } else {
        diagID = ci.getDiagnostics().getCustomDiagID(
            clang::DiagnosticsEngine::Error, "%0 does not exist");
      }

      // Report the diagnostic and return
      ci.getDiagnostics().Report(diagID) << input.getFile();
      beginSourceFileCleanUp(*this, ci);
      return false;
    }
  }

  assert(!instance && "Already processing a source file!");
  assert(!realInput.isEmpty() && "Unexpected empty filename!");
  setCurrentInput(realInput);
  setInstance(&ci);

  if (!ci.hasAllSources()) {
    beginSourceFileCleanUp(*this, ci);
    return false;
  }

  auto &invoc = ci.getInvocation();

  // Include command-line and predefined preprocessor macros. Use either:
  //  * `-cpp/-nocpp`, or
  //  * the file extension (if the user didn't express any preference)
  // to decide whether to include them or not.
  if ((invoc.getPreprocessorOpts().macrosFlag == PPMacrosFlag::Include) ||
      (invoc.getPreprocessorOpts().macrosFlag == PPMacrosFlag::Unknown &&
       getCurrentInput().getMustBePreprocessed())) {
    invoc.setDefaultPredefinitions();
    invoc.collectMacroDefinitions();
  }

  if (!invoc.getFortranOpts().features.IsEnabled(
          Fortran::common::LanguageFeature::CUDA)) {
    // Enable CUDA Fortran if source file is *.cuf/*.CUF and not already
    // enabled.
    invoc.getFortranOpts().features.Enable(
        Fortran::common::LanguageFeature::CUDA,
        getCurrentInput().getIsCUDAFortran());
  }

  // -fpreprocess-include-lines
  invoc.getFortranOpts().expandIncludeLinesInPreprocessedOutput =
      invoc.getPreprocessorOpts().preprocessIncludeLines;

  // Decide between fixed and free form (if the user didn't express any
  // preference, use the file extension to decide)
  if (invoc.getFrontendOpts().fortranForm == FortranForm::Unknown) {
    invoc.getFortranOpts().isFixedForm = getCurrentInput().getIsFixedForm();
  }

  if (!beginSourceFileAction()) {
    beginSourceFileCleanUp(*this, ci);
    return false;
  }

  return true;
}

bool FrontendAction::shouldEraseOutputFiles() {
  return getInstance().getDiagnostics().hasErrorOccurred();
}

llvm::Error FrontendAction::execute() {
  executeAction();

  return llvm::Error::success();
}

void FrontendAction::endSourceFile() {
  CompilerInstance &ci = getInstance();

  // Cleanup the output streams, and erase the output files if instructed by the
  // FrontendAction.
  ci.clearOutputFiles(/*EraseFiles=*/shouldEraseOutputFiles());

  setInstance(nullptr);
  setCurrentInput(FrontendInputFile());
}

bool FrontendAction::runPrescan() {
  CompilerInstance &ci = this->getInstance();
  std::string currentInputPath{getCurrentFileOrBufferName()};
  Fortran::parser::Options parserOptions = ci.getInvocation().getFortranOpts();

  if (ci.getInvocation().getFrontendOpts().fortranForm ==
      FortranForm::Unknown) {
    // Switch between fixed and free form format based on the input file
    // extension.
    //
    // Ideally we should have all Fortran options set before entering this
    // method (i.e. before processing any specific input files). However, we
    // can't decide between fixed and free form based on the file extension
    // earlier than this.
    parserOptions.isFixedForm = getCurrentInput().getIsFixedForm();
  }

  // Prescan. In case of failure, report and return.
  ci.getParsing().Prescan(currentInputPath, parserOptions);

  return !reportFatalScanningErrors();
}

bool FrontendAction::runParse(bool emitMessages) {
  CompilerInstance &ci = this->getInstance();

  // Parse. In case of failure, report and return.
  ci.getParsing().Parse(llvm::outs());

  if (reportFatalParsingErrors()) {
    return false;
  }

  if (emitMessages) {
    // Report any non-fatal diagnostics from getParsing now rather than
    // combining them with messages from semantics.
    ci.getParsing().messages().Emit(llvm::errs(), ci.getAllCookedSources());
  }
  return true;
}

bool FrontendAction::runSemanticChecks() {
  CompilerInstance &ci = this->getInstance();
  std::optional<parser::Program> &parseTree{ci.getParsing().parseTree()};
  assert(parseTree && "Cannot run semantic checks without a parse tree!");

  // Transfer any pending non-fatal messages from parsing to semantics
  // so that they are merged and all printed in order.
  auto &semanticsCtx{ci.getSemanticsContext()};
  semanticsCtx.messages().Annex(std::move(ci.getParsing().messages()));
  semanticsCtx.set_debugModuleWriter(ci.getInvocation().getDebugModuleDir());

  // Prepare semantics
  ci.setSemantics(std::make_unique<Fortran::semantics::Semantics>(semanticsCtx,
                                                                  *parseTree));
  auto &semantics = ci.getSemantics();
  semantics.set_hermeticModuleFileOutput(
      ci.getInvocation().getHermeticModuleFileOutput());

  // Run semantic checks
  semantics.Perform();

  if (reportFatalSemanticErrors()) {
    return false;
  }

  // Report the diagnostics from parsing and the semantic checks
  semantics.EmitMessages(ci.getSemaOutputStream());

  return true;
}

bool FrontendAction::generateRtTypeTables() {
  getInstance().setRtTyTables(
      std::make_unique<Fortran::semantics::RuntimeDerivedTypeTables>(
          BuildRuntimeDerivedTypeTables(getInstance().getSemanticsContext())));

  // The runtime derived type information table builder may find additional
  // semantic errors. Report them.
  if (reportFatalSemanticErrors()) {
    return false;
  }

  return true;
}

template <unsigned N>
bool FrontendAction::reportFatalErrors(const char (&message)[N]) {
  if (!instance->getParsing().messages().empty() &&
      (instance->getInvocation().getWarnAsErr() ||
       instance->getParsing().messages().AnyFatalError())) {
    const unsigned diagID = instance->getDiagnostics().getCustomDiagID(
        clang::DiagnosticsEngine::Error, message);
    instance->getDiagnostics().Report(diagID) << getCurrentFileOrBufferName();
    instance->getParsing().messages().Emit(llvm::errs(),
                                           instance->getAllCookedSources());
    return true;
  }
  if (instance->getParsing().parseTree().has_value() &&
      !instance->getParsing().consumedWholeFile()) {
    // Parsing failed without error.
    const unsigned diagID = instance->getDiagnostics().getCustomDiagID(
        clang::DiagnosticsEngine::Error, message);
    instance->getDiagnostics().Report(diagID) << getCurrentFileOrBufferName();
    instance->getParsing().messages().Emit(llvm::errs(),
                                           instance->getAllCookedSources());
    instance->getParsing().EmitMessage(
        llvm::errs(), instance->getParsing().finalRestingPlace(),
        "parser FAIL (final position)", "error: ", llvm::raw_ostream::RED);
    return true;
  }
  return false;
}

bool FrontendAction::reportFatalSemanticErrors() {
  auto &diags = instance->getDiagnostics();
  auto &sema = instance->getSemantics();

  if (instance->getSemantics().AnyFatalError()) {
    unsigned diagID = diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
                                            "Semantic errors in %0");
    diags.Report(diagID) << getCurrentFileOrBufferName();
    sema.EmitMessages(instance->getSemaOutputStream());

    return true;
  }

  return false;
}
