//===- CompilerInvocation.h - Compiler Invocation Helper Data ---*- 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 LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H
#define LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H

#include "clang/APINotes/APINotesOptions.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileSystemOptions.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/LangStandard.h"
#include "clang/Frontend/DependencyOutputOptions.h"
#include "clang/Frontend/FrontendOptions.h"
#include "clang/Frontend/MigratorOptions.h"
#include "clang/Frontend/PreprocessorOutputOptions.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/ArrayRef.h"
#include <memory>
#include <string>

namespace llvm {

class Triple;

namespace opt {

class ArgList;

} // namespace opt

namespace vfs {

class FileSystem;

} // namespace vfs

} // namespace llvm

namespace clang {

class DiagnosticsEngine;
class HeaderSearchOptions;
class PreprocessorOptions;
class TargetOptions;

// This lets us create the DiagnosticsEngine with a properly-filled-out
// DiagnosticOptions instance.
std::unique_ptr<DiagnosticOptions>
CreateAndPopulateDiagOpts(ArrayRef<const char *> Argv);

/// Fill out Opts based on the options given in Args.
///
/// Args must have been created from the OptTable returned by
/// createCC1OptTable().
///
/// When errors are encountered, return false and, if Diags is non-null,
/// report the error(s).
bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args,
                         DiagnosticsEngine *Diags = nullptr,
                         bool DefaultDiagColor = true);

/// The base class of CompilerInvocation. It keeps individual option objects
/// behind reference-counted pointers, which is useful for clients that want to
/// keep select option objects alive (even after CompilerInvocation gets
/// destroyed) without making a copy.
class CompilerInvocationBase {
protected:
  /// Options controlling the language variant.
  std::shared_ptr<LangOptions> LangOpts;

  /// Options controlling the target.
  std::shared_ptr<TargetOptions> TargetOpts;

  /// Options controlling the diagnostic engine.
  IntrusiveRefCntPtr<DiagnosticOptions> DiagnosticOpts;

  /// Options controlling the \#include directive.
  std::shared_ptr<HeaderSearchOptions> HSOpts;

  /// Options controlling the preprocessor (aside from \#include handling).
  std::shared_ptr<PreprocessorOptions> PPOpts;

  /// Options controlling the static analyzer.
  AnalyzerOptionsRef AnalyzerOpts;

  std::shared_ptr<MigratorOptions> MigratorOpts;

  /// Options controlling API notes.
  std::shared_ptr<APINotesOptions> APINotesOpts;

  /// Options controlling IRgen and the backend.
  std::shared_ptr<CodeGenOptions> CodeGenOpts;

  /// Options controlling file system operations.
  std::shared_ptr<FileSystemOptions> FSOpts;

  /// Options controlling the frontend itself.
  std::shared_ptr<FrontendOptions> FrontendOpts;

  /// Options controlling dependency output.
  std::shared_ptr<DependencyOutputOptions> DependencyOutputOpts;

  /// Options controlling preprocessed output.
  std::shared_ptr<PreprocessorOutputOptions> PreprocessorOutputOpts;

  /// Dummy tag type whose instance can be passed into the constructor to
  /// prevent creation of the reference-counted option objects.
  struct EmptyConstructor {};

  CompilerInvocationBase();
  CompilerInvocationBase(EmptyConstructor) {}
  CompilerInvocationBase(const CompilerInvocationBase &X) = delete;
  CompilerInvocationBase(CompilerInvocationBase &&X) = default;
  CompilerInvocationBase &operator=(const CompilerInvocationBase &X) = delete;
  CompilerInvocationBase &deep_copy_assign(const CompilerInvocationBase &X);
  CompilerInvocationBase &shallow_copy_assign(const CompilerInvocationBase &X);
  CompilerInvocationBase &operator=(CompilerInvocationBase &&X) = default;
  ~CompilerInvocationBase() = default;

public:
  /// Const getters.
  /// @{
  const LangOptions &getLangOpts() const { return *LangOpts; }
  const TargetOptions &getTargetOpts() const { return *TargetOpts; }
  const DiagnosticOptions &getDiagnosticOpts() const { return *DiagnosticOpts; }
  const HeaderSearchOptions &getHeaderSearchOpts() const { return *HSOpts; }
  const PreprocessorOptions &getPreprocessorOpts() const { return *PPOpts; }
  const AnalyzerOptions &getAnalyzerOpts() const { return *AnalyzerOpts; }
  const MigratorOptions &getMigratorOpts() const { return *MigratorOpts; }
  const APINotesOptions &getAPINotesOpts() const { return *APINotesOpts; }
  const CodeGenOptions &getCodeGenOpts() const { return *CodeGenOpts; }
  const FileSystemOptions &getFileSystemOpts() const { return *FSOpts; }
  const FrontendOptions &getFrontendOpts() const { return *FrontendOpts; }
  const DependencyOutputOptions &getDependencyOutputOpts() const {
    return *DependencyOutputOpts;
  }
  const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
    return *PreprocessorOutputOpts;
  }
  /// @}

  /// Command line generation.
  /// @{
  using StringAllocator = llvm::function_ref<const char *(const Twine &)>;
  /// Generate cc1-compatible command line arguments from this instance.
  ///
  /// \param [out] Args - The generated arguments. Note that the caller is
  /// responsible for inserting the path to the clang executable and "-cc1" if
  /// desired.
  /// \param SA - A function that given a Twine can allocate storage for a given
  /// command line argument and return a pointer to the newly allocated string.
  /// The returned pointer is what gets appended to Args.
  void generateCC1CommandLine(llvm::SmallVectorImpl<const char *> &Args,
                              StringAllocator SA) const {
    generateCC1CommandLine([&](const Twine &Arg) {
      // No need to allocate static string literals.
      Args.push_back(Arg.isSingleStringLiteral()
                         ? Arg.getSingleStringRef().data()
                         : SA(Arg));
    });
  }

  using ArgumentConsumer = llvm::function_ref<void(const Twine &)>;
  /// Generate cc1-compatible command line arguments from this instance.
  ///
  /// \param Consumer - Callback that gets invoked for every single generated
  /// command line argument.
  void generateCC1CommandLine(ArgumentConsumer Consumer) const;

  /// Generate cc1-compatible command line arguments from this instance,
  /// wrapping the result as a std::vector<std::string>.
  ///
  /// This is a (less-efficient) wrapper over generateCC1CommandLine().
  std::vector<std::string> getCC1CommandLine() const;

private:
  /// Generate command line options from DiagnosticOptions.
  static void GenerateDiagnosticArgs(const DiagnosticOptions &Opts,
                                     ArgumentConsumer Consumer,
                                     bool DefaultDiagColor);

  /// Generate command line options from LangOptions.
  static void GenerateLangArgs(const LangOptions &Opts,
                               ArgumentConsumer Consumer, const llvm::Triple &T,
                               InputKind IK);

  // Generate command line options from CodeGenOptions.
  static void GenerateCodeGenArgs(const CodeGenOptions &Opts,
                                  ArgumentConsumer Consumer,
                                  const llvm::Triple &T,
                                  const std::string &OutputFile,
                                  const LangOptions *LangOpts);
  /// @}
};

class CowCompilerInvocation;

/// Helper class for holding the data necessary to invoke the compiler.
///
/// This class is designed to represent an abstract "invocation" of the
/// compiler, including data such as the include paths, the code generation
/// options, the warning flags, and so on.
class CompilerInvocation : public CompilerInvocationBase {
public:
  CompilerInvocation() = default;
  CompilerInvocation(const CompilerInvocation &X)
      : CompilerInvocationBase(EmptyConstructor{}) {
    deep_copy_assign(X);
  }
  CompilerInvocation(CompilerInvocation &&) = default;
  CompilerInvocation &operator=(const CompilerInvocation &X) {
    deep_copy_assign(X);
    return *this;
  }
  ~CompilerInvocation() = default;

  explicit CompilerInvocation(const CowCompilerInvocation &X);
  CompilerInvocation &operator=(const CowCompilerInvocation &X);

  /// Const getters.
  /// @{
  // Note: These need to be pulled in manually. Otherwise, they get hidden by
  // the mutable getters with the same names.
  using CompilerInvocationBase::getLangOpts;
  using CompilerInvocationBase::getTargetOpts;
  using CompilerInvocationBase::getDiagnosticOpts;
  using CompilerInvocationBase::getHeaderSearchOpts;
  using CompilerInvocationBase::getPreprocessorOpts;
  using CompilerInvocationBase::getAnalyzerOpts;
  using CompilerInvocationBase::getMigratorOpts;
  using CompilerInvocationBase::getAPINotesOpts;
  using CompilerInvocationBase::getCodeGenOpts;
  using CompilerInvocationBase::getFileSystemOpts;
  using CompilerInvocationBase::getFrontendOpts;
  using CompilerInvocationBase::getDependencyOutputOpts;
  using CompilerInvocationBase::getPreprocessorOutputOpts;
  /// @}

  /// Mutable getters.
  /// @{
  LangOptions &getLangOpts() { return *LangOpts; }
  TargetOptions &getTargetOpts() { return *TargetOpts; }
  DiagnosticOptions &getDiagnosticOpts() { return *DiagnosticOpts; }
  HeaderSearchOptions &getHeaderSearchOpts() { return *HSOpts; }
  PreprocessorOptions &getPreprocessorOpts() { return *PPOpts; }
  AnalyzerOptions &getAnalyzerOpts() { return *AnalyzerOpts; }
  MigratorOptions &getMigratorOpts() { return *MigratorOpts; }
  APINotesOptions &getAPINotesOpts() { return *APINotesOpts; }
  CodeGenOptions &getCodeGenOpts() { return *CodeGenOpts; }
  FileSystemOptions &getFileSystemOpts() { return *FSOpts; }
  FrontendOptions &getFrontendOpts() { return *FrontendOpts; }
  DependencyOutputOptions &getDependencyOutputOpts() {
    return *DependencyOutputOpts;
  }
  PreprocessorOutputOptions &getPreprocessorOutputOpts() {
    return *PreprocessorOutputOpts;
  }
  /// @}

  /// Base class internals.
  /// @{
  using CompilerInvocationBase::LangOpts;
  using CompilerInvocationBase::TargetOpts;
  using CompilerInvocationBase::DiagnosticOpts;
  std::shared_ptr<HeaderSearchOptions> getHeaderSearchOptsPtr() {
    return HSOpts;
  }
  std::shared_ptr<PreprocessorOptions> getPreprocessorOptsPtr() {
    return PPOpts;
  }
  std::shared_ptr<LangOptions> getLangOptsPtr() { return LangOpts; }
  /// @}

  /// Create a compiler invocation from a list of input options.
  /// \returns true on success.
  ///
  /// \returns false if an error was encountered while parsing the arguments
  /// and attempts to recover and continue parsing the rest of the arguments.
  /// The recovery is best-effort and only guarantees that \p Res will end up in
  /// one of the vaild-to-access (albeit arbitrary) states.
  ///
  /// \param [out] Res - The resulting invocation.
  /// \param [in] CommandLineArgs - Array of argument strings, this must not
  /// contain "-cc1".
  static bool CreateFromArgs(CompilerInvocation &Res,
                             ArrayRef<const char *> CommandLineArgs,
                             DiagnosticsEngine &Diags,
                             const char *Argv0 = nullptr);

  /// Get the directory where the compiler headers
  /// reside, relative to the compiler binary (found by the passed in
  /// arguments).
  ///
  /// \param Argv0 - The program path (from argv[0]), for finding the builtin
  /// compiler path.
  /// \param MainAddr - The address of main (or some other function in the main
  /// executable), for finding the builtin compiler path.
  static std::string GetResourcesPath(const char *Argv0, void *MainAddr);

  /// Retrieve a module hash string that is suitable for uniquely
  /// identifying the conditions under which the module was built.
  std::string getModuleHash() const;

  /// Check that \p Args can be parsed and re-serialized without change,
  /// emiting diagnostics for any differences.
  ///
  /// This check is only suitable for command-lines that are expected to already
  /// be canonical.
  ///
  /// \return false if there are any errors.
  static bool checkCC1RoundTrip(ArrayRef<const char *> Args,
                                DiagnosticsEngine &Diags,
                                const char *Argv0 = nullptr);

  /// Reset all of the options that are not considered when building a
  /// module.
  void resetNonModularOptions();

  /// Disable implicit modules and canonicalize options that are only used by
  /// implicit modules.
  void clearImplicitModuleBuildOptions();

private:
  static bool CreateFromArgsImpl(CompilerInvocation &Res,
                                 ArrayRef<const char *> CommandLineArgs,
                                 DiagnosticsEngine &Diags, const char *Argv0);

  /// Parse command line options that map to LangOptions.
  static bool ParseLangArgs(LangOptions &Opts, llvm::opt::ArgList &Args,
                            InputKind IK, const llvm::Triple &T,
                            std::vector<std::string> &Includes,
                            DiagnosticsEngine &Diags);

  /// Parse command line options that map to CodeGenOptions.
  static bool ParseCodeGenArgs(CodeGenOptions &Opts, llvm::opt::ArgList &Args,
                               InputKind IK, DiagnosticsEngine &Diags,
                               const llvm::Triple &T,
                               const std::string &OutputFile,
                               const LangOptions &LangOptsRef);
};

/// Same as \c CompilerInvocation, but with copy-on-write optimization.
class CowCompilerInvocation : public CompilerInvocationBase {
public:
  CowCompilerInvocation() = default;
  CowCompilerInvocation(const CowCompilerInvocation &X)
      : CompilerInvocationBase(EmptyConstructor{}) {
    shallow_copy_assign(X);
  }
  CowCompilerInvocation(CowCompilerInvocation &&) = default;
  CowCompilerInvocation &operator=(const CowCompilerInvocation &X) {
    shallow_copy_assign(X);
    return *this;
  }
  ~CowCompilerInvocation() = default;

  CowCompilerInvocation(const CompilerInvocation &X)
      : CompilerInvocationBase(EmptyConstructor{}) {
    deep_copy_assign(X);
  }

  CowCompilerInvocation(CompilerInvocation &&X)
      : CompilerInvocationBase(std::move(X)) {}

  // Const getters are inherited from the base class.

  /// Mutable getters.
  /// @{
  LangOptions &getMutLangOpts();
  TargetOptions &getMutTargetOpts();
  DiagnosticOptions &getMutDiagnosticOpts();
  HeaderSearchOptions &getMutHeaderSearchOpts();
  PreprocessorOptions &getMutPreprocessorOpts();
  AnalyzerOptions &getMutAnalyzerOpts();
  MigratorOptions &getMutMigratorOpts();
  APINotesOptions &getMutAPINotesOpts();
  CodeGenOptions &getMutCodeGenOpts();
  FileSystemOptions &getMutFileSystemOpts();
  FrontendOptions &getMutFrontendOpts();
  DependencyOutputOptions &getMutDependencyOutputOpts();
  PreprocessorOutputOptions &getMutPreprocessorOutputOpts();
  /// @}
};

IntrusiveRefCntPtr<llvm::vfs::FileSystem>
createVFSFromCompilerInvocation(const CompilerInvocation &CI,
                                DiagnosticsEngine &Diags);

IntrusiveRefCntPtr<llvm::vfs::FileSystem> createVFSFromCompilerInvocation(
    const CompilerInvocation &CI, DiagnosticsEngine &Diags,
    IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS);

IntrusiveRefCntPtr<llvm::vfs::FileSystem>
createVFSFromOverlayFiles(ArrayRef<std::string> VFSOverlayFiles,
                          DiagnosticsEngine &Diags,
                          IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS);

} // namespace clang

#endif // LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H
