//===--- ExecuteCompilerInvocation.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
//
//===----------------------------------------------------------------------===//
//
// This file holds ExecuteCompilerInvocation(). It is split into its own file to
// minimize the impact of pulling in essentially everything else in Clang.
//
//===----------------------------------------------------------------------===//

#include "clang/Basic/DiagnosticFrontend.h"
#include "clang/CodeGen/CodeGenAction.h"
#include "clang/Config/config.h"
#include "clang/ExtractAPI/FrontendActions.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/FrontendPluginRegistry.h"
#include "clang/Frontend/SSAFOptions.h"
#include "clang/Frontend/Utils.h"
#include "clang/FrontendTool/Utils.h"
#include "clang/Options/Options.h"
#include "clang/Rewrite/Frontend/FrontendActions.h"
#include "clang/ScalableStaticAnalysis/Frontend/SourceTransformationFrontendAction.h"
#include "clang/ScalableStaticAnalysis/Frontend/TUSummaryExtractorFrontendAction.h"
#include "clang/ScalableStaticAnalysis/SSAFForceLinker.h" // IWYU pragma: keep
#include "clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h"
#include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Support/BuryPointer.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/ErrorHandling.h"

#if CLANG_ENABLE_CIR
#include "mlir/IR/AsmState.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/Pass/PassManager.h"
#include "clang/CIR/Dialect/Passes.h"
#include "clang/CIR/FrontendAction/CIRGenAction.h"
#endif

using namespace clang;
using namespace llvm::opt;

namespace clang {

static std::unique_ptr<FrontendAction>
CreateFrontendBaseAction(CompilerInstance &CI) {
  using namespace clang::frontend;
  StringRef Action("unknown");
  (void)Action;

  unsigned UseCIR = CI.getFrontendOpts().UseClangIRPipeline;
  frontend::ActionKind Act = CI.getFrontendOpts().ProgramAction;
  bool EmitsCIR = Act == EmitCIR;

  if (!UseCIR && EmitsCIR)
    llvm::report_fatal_error("-emit-cir and only valid when using -fclangir");

  switch (CI.getFrontendOpts().ProgramAction) {
  case ASTDeclList:            return std::make_unique<ASTDeclListAction>();
  case ASTDump:                return std::make_unique<ASTDumpAction>();
  case ASTPrint:               return std::make_unique<ASTPrintAction>();
  case ASTView:                return std::make_unique<ASTViewAction>();
  case DumpCompilerOptions:
    return std::make_unique<DumpCompilerOptionsAction>();
  case DumpRawTokens:          return std::make_unique<DumpRawTokensAction>();
  case DumpTokens:             return std::make_unique<DumpTokensAction>();
  case EmitAssembly:
#if CLANG_ENABLE_CIR
    if (UseCIR)
      return std::make_unique<cir::EmitAssemblyAction>();
#endif
    return std::make_unique<EmitAssemblyAction>();
  case EmitBC:
#if CLANG_ENABLE_CIR
    if (UseCIR)
      return std::make_unique<cir::EmitBCAction>();
#endif
    return std::make_unique<EmitBCAction>();
  case EmitCIR:
#if CLANG_ENABLE_CIR
    return std::make_unique<cir::EmitCIRAction>();
#else
    CI.getDiagnostics().Report(diag::err_fe_cir_not_built);
    return nullptr;
#endif
  case EmitHTML:               return std::make_unique<HTMLPrintAction>();
  case EmitLLVM: {
#if CLANG_ENABLE_CIR
    if (UseCIR)
      return std::make_unique<cir::EmitLLVMAction>();
#endif
    return std::make_unique<EmitLLVMAction>();
  }
  case EmitLLVMOnly:           return std::make_unique<EmitLLVMOnlyAction>();
  case EmitCodeGenOnly:        return std::make_unique<EmitCodeGenOnlyAction>();
  case EmitObj:
#if CLANG_ENABLE_CIR
    if (UseCIR)
      return std::make_unique<cir::EmitObjAction>();
#endif
    return std::make_unique<EmitObjAction>();
  case ExtractAPI:
    return std::make_unique<ExtractAPIAction>();
  case FixIt:                  return std::make_unique<FixItAction>();
  case GenerateModule:
    return std::make_unique<GenerateModuleFromModuleMapAction>();
  case GenerateModuleInterface:
    return std::make_unique<GenerateModuleInterfaceAction>();
  case GenerateReducedModuleInterface:
    return std::make_unique<GenerateReducedModuleInterfaceAction>();
  case GenerateHeaderUnit:
    return std::make_unique<GenerateHeaderUnitAction>();
  case GeneratePCH:            return std::make_unique<GeneratePCHAction>();
  case GenerateInterfaceStubs:
    return std::make_unique<GenerateInterfaceStubsAction>();
  case InitOnly:               return std::make_unique<InitOnlyAction>();
  case ParseSyntaxOnly:        return std::make_unique<SyntaxOnlyAction>();
  case ModuleFileInfo:         return std::make_unique<DumpModuleInfoAction>();
  case VerifyPCH:
    return std::make_unique<VerifyPCHAction>();

  case PluginAction: {
    for (const FrontendPluginRegistry::entry &Plugin :
         FrontendPluginRegistry::entries()) {
      if (Plugin.getName() == CI.getFrontendOpts().ActionName) {
        std::unique_ptr<PluginASTAction> P(Plugin.instantiate());
        if ((P->getActionType() != PluginASTAction::ReplaceAction &&
             P->getActionType() != PluginASTAction::CmdlineAfterMainAction) ||
            !P->ParseArgs(
                CI,
                CI.getFrontendOpts().PluginArgs[std::string(Plugin.getName())]))
          return nullptr;
        return std::move(P);
      }
    }

    CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name)
      << CI.getFrontendOpts().ActionName;
    return nullptr;
  }

  case PrintPreamble:          return std::make_unique<PrintPreambleAction>();
  case PrintPreprocessedInput: {
    if (CI.getPreprocessorOutputOpts().RewriteIncludes ||
        CI.getPreprocessorOutputOpts().RewriteImports)
      return std::make_unique<RewriteIncludesAction>();
    return std::make_unique<PrintPreprocessedAction>();
  }

  case RewriteMacros:          return std::make_unique<RewriteMacrosAction>();
  case RewriteTest:            return std::make_unique<RewriteTestAction>();
#if CLANG_ENABLE_OBJC_REWRITER
  case RewriteObjC:            return std::make_unique<RewriteObjCAction>();
#else
  case RewriteObjC:            Action = "RewriteObjC"; break;
#endif
#if CLANG_ENABLE_STATIC_ANALYZER
  case RunAnalysis:            return std::make_unique<ento::AnalysisAction>();
#else
  case RunAnalysis:            Action = "RunAnalysis"; break;
#endif
  case RunPreprocessorOnly:    return std::make_unique<PreprocessOnlyAction>();
  case PrintDependencyDirectivesSourceMinimizerOutput:
    return std::make_unique<PrintDependencyDirectivesSourceMinimizerAction>();
  }

#if !CLANG_ENABLE_STATIC_ANALYZER || !CLANG_ENABLE_OBJC_REWRITER
  CI.getDiagnostics().Report(diag::err_fe_action_not_available) << Action;
  return 0;
#else
  llvm_unreachable("Invalid program action!");
#endif
}

std::unique_ptr<FrontendAction>
CreateFrontendAction(CompilerInstance &CI) {
  // Create the underlying action.
  std::unique_ptr<FrontendAction> Act = CreateFrontendBaseAction(CI);
  if (!Act)
    return nullptr;

  const FrontendOptions &FEOpts = CI.getFrontendOpts();

  if (CI.getLangOpts().HLSL)
    Act = std::make_unique<HLSLFrontendAction>(std::move(Act));

  if (FEOpts.FixAndRecompile) {
    Act = std::make_unique<FixItRecompile>(std::move(Act));
  }

  // Wrap the base FE action in an extract api action to generate
  // symbol graph as a biproduct of compilation (enabled with
  // --emit-symbol-graph option)
  if (FEOpts.EmitSymbolGraph) {
    if (FEOpts.SymbolGraphOutputDir.empty()) {
      CI.getDiagnostics().Report(diag::warn_missing_symbol_graph_dir);
      CI.getFrontendOpts().SymbolGraphOutputDir = ".";
    }
    CI.getCodeGenOpts().ClearASTBeforeBackend = false;
    Act = std::make_unique<WrappingExtractAPIAction>(std::move(Act));
  }

  // If there are any AST files to merge, create a frontend action
  // adaptor to perform the merge.
  if (!FEOpts.ASTMergeFiles.empty())
    Act = std::make_unique<ASTMergeAction>(std::move(Act),
                                            FEOpts.ASTMergeFiles);

  if (!CI.getSSAFOpts().TUSummaryFile.empty()) {
    Act = std::make_unique<ssaf::TUSummaryExtractorFrontendAction>(
        std::move(Act));
  }
  // Enter the source-transformation action when the transformation option is
  // set, and also when only an output option (--ssaf-src-edit-file= /
  // --ssaf-transformation-report-file=) is set — the action's
  // reportOrphanOptionMisuse then diagnoses that as a reverse orphan rather
  // than silently ignoring the option.
  if (!CI.getSSAFOpts().SourceTransformation.empty() ||
      !CI.getSSAFOpts().SrcEditFile.empty() ||
      !CI.getSSAFOpts().TransformationReportFile.empty()) {
    Act = std::make_unique<ssaf::SourceTransformationFrontendAction>(
        std::move(Act));
  }
  return Act;
}

bool ExecuteCompilerInvocation(CompilerInstance *Clang) {
  unsigned NumErrorsBefore = Clang->getDiagnostics().getNumErrors();

  // Honor -help.
  if (Clang->getFrontendOpts().ShowHelp) {
    getDriverOptTable().printHelp(
        llvm::outs(), "clang -cc1 [options] file...",
        "LLVM 'Clang' Compiler: http://clang.llvm.org",
        /*ShowHidden=*/false, /*ShowAllAliases=*/false,
        llvm::opt::Visibility(options::CC1Option));
    return true;
  }

  // Honor -version.
  //
  // FIXME: Use a better -version message?
  if (Clang->getFrontendOpts().ShowVersion) {
    llvm::cl::PrintVersionMessage();
    return true;
  }

  Clang->LoadRequestedPlugins();

  // Honor -mllvm.
  //
  // FIXME: Remove this, one day.
  // This should happen AFTER plugins have been loaded!
  if (!Clang->getFrontendOpts().LLVMArgs.empty()) {
    unsigned NumArgs = Clang->getFrontendOpts().LLVMArgs.size();
    auto Args = std::make_unique<const char*[]>(NumArgs + 2);
    Args[0] = "clang (LLVM option parsing)";
    for (unsigned i = 0; i != NumArgs; ++i)
      Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str();
    Args[NumArgs + 1] = nullptr;
    llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get(), /*Overview=*/"",
                                      /*Errs=*/nullptr,
                                      /*VFS=*/&Clang->getVirtualFileSystem());
  }

#if CLANG_ENABLE_STATIC_ANALYZER
  // These should happen AFTER plugins have been loaded!

  AnalyzerOptions &AnOpts = Clang->getAnalyzerOpts();

  // Honor -analyzer-checker-help and -analyzer-checker-help-hidden.
  if (AnOpts.ShowCheckerHelp || AnOpts.ShowCheckerHelpAlpha ||
      AnOpts.ShowCheckerHelpDeveloper) {
    ento::printCheckerHelp(llvm::outs(), *Clang);
    return true;
  }

  // Honor -analyzer-checker-option-help.
  if (AnOpts.ShowCheckerOptionList || AnOpts.ShowCheckerOptionAlphaList ||
      AnOpts.ShowCheckerOptionDeveloperList) {
    ento::printCheckerConfigList(llvm::outs(), *Clang);
    return true;
  }

  // Honor -analyzer-list-enabled-checkers.
  if (AnOpts.ShowEnabledCheckerList) {
    ento::printEnabledCheckerList(llvm::outs(), *Clang);
    return true;
  }

  // Honor -analyzer-config-help.
  if (AnOpts.ShowConfigOptionsList) {
    ento::printAnalyzerConfigList(llvm::outs());
    return true;
  }
#endif

#if CLANG_ENABLE_CIR
  if (!Clang->getFrontendOpts().MLIRArgs.empty()) {
    mlir::registerCIRPasses();
    mlir::registerMLIRContextCLOptions();
    mlir::registerPassManagerCLOptions();
    mlir::registerAsmPrinterCLOptions();
    unsigned NumArgs = Clang->getFrontendOpts().MLIRArgs.size();
    auto Args = std::make_unique<const char *[]>(NumArgs + 2);
    Args[0] = "clang (MLIR option parsing)";
    for (unsigned i = 0; i != NumArgs; ++i)
      Args[i + 1] = Clang->getFrontendOpts().MLIRArgs[i].c_str();
    Args[NumArgs + 1] = nullptr;
    llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get(),
                                      /*Description=*/"", /*Errs=*/nullptr,
                                      &Clang->getVirtualFileSystem());
  }
#endif

  // If there were errors in the above, don't do anything else.
  // This intentionally ignores errors emitted before this function to
  // accommodate lenient callers that decided to make progress despite errors.
  if (Clang->getDiagnostics().getNumErrors() != NumErrorsBefore)
    return false;

  // Create and execute the frontend action.
  std::unique_ptr<FrontendAction> Act(CreateFrontendAction(*Clang));
  if (!Act)
    return false;
  bool Success = Clang->ExecuteAction(*Act);
  if (Clang->getFrontendOpts().DisableFree)
    llvm::BuryPointer(std::move(Act));
  return Success;
}

} // namespace clang
