//===-- CompilerInstance.h - Clang Compiler Instance ------------*- 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_COMPILERINSTANCE_H_
#define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_

#include "clang/AST/ASTConsumer.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Frontend/Utils.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/ModuleLoader.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/BuryPointer.h"
#include "llvm/Support/FileSystem.h"
#include <cassert>
#include <list>
#include <memory>
#include <string>
#include <utility>

namespace llvm {
class raw_fd_ostream;
class Timer;
class TimerGroup;
}

namespace clang {
class ASTContext;
class ASTReader;
class CodeCompleteConsumer;
class DiagnosticsEngine;
class DiagnosticConsumer;
class ExternalASTSource;
class FileEntry;
class FileManager;
class FrontendAction;
class InMemoryModuleCache;
class Module;
class Preprocessor;
class Sema;
class SourceManager;
class TargetInfo;
enum class DisableValidationForModuleKind;

/// CompilerInstance - Helper class for managing a single instance of the Clang
/// compiler.
///
/// The CompilerInstance serves two purposes:
///  (1) It manages the various objects which are necessary to run the compiler,
///      for example the preprocessor, the target information, and the AST
///      context.
///  (2) It provides utility routines for constructing and manipulating the
///      common Clang objects.
///
/// The compiler instance generally owns the instance of all the objects that it
/// manages. However, clients can still share objects by manually setting the
/// object and retaking ownership prior to destroying the CompilerInstance.
///
/// The compiler instance is intended to simplify clients, but not to lock them
/// in to the compiler instance for everything. When possible, utility functions
/// come in two forms; a short form that reuses the CompilerInstance objects,
/// and a long form that takes explicit instances of any required objects.
class CompilerInstance : public ModuleLoader {
  /// The options used in this compiler instance.
  std::shared_ptr<CompilerInvocation> Invocation;

  /// The diagnostics engine instance.
  IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics;

  /// The target being compiled for.
  IntrusiveRefCntPtr<TargetInfo> Target;

  /// Auxiliary Target info.
  IntrusiveRefCntPtr<TargetInfo> AuxTarget;

  /// The file manager.
  IntrusiveRefCntPtr<FileManager> FileMgr;

  /// The source manager.
  IntrusiveRefCntPtr<SourceManager> SourceMgr;

  /// The cache of PCM files.
  IntrusiveRefCntPtr<InMemoryModuleCache> ModuleCache;

  /// The preprocessor.
  std::shared_ptr<Preprocessor> PP;

  /// The AST context.
  IntrusiveRefCntPtr<ASTContext> Context;

  /// An optional sema source that will be attached to sema.
  IntrusiveRefCntPtr<ExternalSemaSource> ExternalSemaSrc;

  /// The AST consumer.
  std::unique_ptr<ASTConsumer> Consumer;

  /// The code completion consumer.
  std::unique_ptr<CodeCompleteConsumer> CompletionConsumer;

  /// The semantic analysis object.
  std::unique_ptr<Sema> TheSema;

  /// The frontend timer group.
  std::unique_ptr<llvm::TimerGroup> FrontendTimerGroup;

  /// The frontend timer.
  std::unique_ptr<llvm::Timer> FrontendTimer;

  /// The ASTReader, if one exists.
  IntrusiveRefCntPtr<ASTReader> TheASTReader;

  /// The module dependency collector for crashdumps
  std::shared_ptr<ModuleDependencyCollector> ModuleDepCollector;

  /// The module provider.
  std::shared_ptr<PCHContainerOperations> ThePCHContainerOperations;

  std::vector<std::shared_ptr<DependencyCollector>> DependencyCollectors;

  /// The set of top-level modules that has already been built on the
  /// fly as part of this overall compilation action.
  std::map<std::string, std::string, std::less<>> BuiltModules;

  /// Should we delete the BuiltModules when we're done?
  bool DeleteBuiltModules = true;

  /// The location of the module-import keyword for the last module
  /// import.
  SourceLocation LastModuleImportLoc;

  /// The result of the last module import.
  ///
  ModuleLoadResult LastModuleImportResult;

  /// Whether we should (re)build the global module index once we
  /// have finished with this translation unit.
  bool BuildGlobalModuleIndex = false;

  /// We have a full global module index, with all modules.
  bool HaveFullGlobalModuleIndex = false;

  /// One or more modules failed to build.
  bool DisableGeneratingGlobalModuleIndex = false;

  /// The stream for verbose output if owned, otherwise nullptr.
  std::unique_ptr<raw_ostream> OwnedVerboseOutputStream;

  /// The stream for verbose output.
  raw_ostream *VerboseOutputStream = &llvm::errs();

  /// Holds information about the output file.
  ///
  /// If TempFilename is not empty we must rename it to Filename at the end.
  /// TempFilename may be empty and Filename non-empty if creating the temporary
  /// failed.
  struct OutputFile {
    std::string Filename;
    Optional<llvm::sys::fs::TempFile> File;

    OutputFile(std::string filename, Optional<llvm::sys::fs::TempFile> file)
        : Filename(std::move(filename)), File(std::move(file)) {}
  };

  /// The list of active output files.
  std::list<OutputFile> OutputFiles;

  /// Force an output buffer.
  std::unique_ptr<llvm::raw_pwrite_stream> OutputStream;

  CompilerInstance(const CompilerInstance &) = delete;
  void operator=(const CompilerInstance &) = delete;
public:
  explicit CompilerInstance(
      std::shared_ptr<PCHContainerOperations> PCHContainerOps =
          std::make_shared<PCHContainerOperations>(),
      InMemoryModuleCache *SharedModuleCache = nullptr);
  ~CompilerInstance() override;

  /// @name High-Level Operations
  /// {

  /// ExecuteAction - Execute the provided action against the compiler's
  /// CompilerInvocation object.
  ///
  /// This function makes the following assumptions:
  ///
  ///  - The invocation options should be initialized. This function does not
  ///    handle the '-help' or '-version' options, clients should handle those
  ///    directly.
  ///
  ///  - The diagnostics engine should have already been created by the client.
  ///
  ///  - No other CompilerInstance state should have been initialized (this is
  ///    an unchecked error).
  ///
  ///  - Clients should have initialized any LLVM target features that may be
  ///    required.
  ///
  ///  - Clients should eventually call llvm_shutdown() upon the completion of
  ///    this routine to ensure that any managed objects are properly destroyed.
  ///
  /// Note that this routine may write output to 'stderr'.
  ///
  /// \param Act - The action to execute.
  /// \return - True on success.
  //
  // FIXME: Eliminate the llvm_shutdown requirement, that should either be part
  // of the context or else not CompilerInstance specific.
  bool ExecuteAction(FrontendAction &Act);

  /// }
  /// @name Compiler Invocation and Options
  /// {

  bool hasInvocation() const { return Invocation != nullptr; }

  CompilerInvocation &getInvocation() {
    assert(Invocation && "Compiler instance has no invocation!");
    return *Invocation;
  }

  /// setInvocation - Replace the current invocation.
  void setInvocation(std::shared_ptr<CompilerInvocation> Value);

  /// Indicates whether we should (re)build the global module index.
  bool shouldBuildGlobalModuleIndex() const;

  /// Set the flag indicating whether we should (re)build the global
  /// module index.
  void setBuildGlobalModuleIndex(bool Build) {
    BuildGlobalModuleIndex = Build;
  }

  /// }
  /// @name Forwarding Methods
  /// {

  AnalyzerOptionsRef getAnalyzerOpts() {
    return Invocation->getAnalyzerOpts();
  }

  CodeGenOptions &getCodeGenOpts() {
    return Invocation->getCodeGenOpts();
  }
  const CodeGenOptions &getCodeGenOpts() const {
    return Invocation->getCodeGenOpts();
  }

  DependencyOutputOptions &getDependencyOutputOpts() {
    return Invocation->getDependencyOutputOpts();
  }
  const DependencyOutputOptions &getDependencyOutputOpts() const {
    return Invocation->getDependencyOutputOpts();
  }

  DiagnosticOptions &getDiagnosticOpts() {
    return Invocation->getDiagnosticOpts();
  }
  const DiagnosticOptions &getDiagnosticOpts() const {
    return Invocation->getDiagnosticOpts();
  }

  FileSystemOptions &getFileSystemOpts() {
    return Invocation->getFileSystemOpts();
  }
  const FileSystemOptions &getFileSystemOpts() const {
    return Invocation->getFileSystemOpts();
  }

  FrontendOptions &getFrontendOpts() {
    return Invocation->getFrontendOpts();
  }
  const FrontendOptions &getFrontendOpts() const {
    return Invocation->getFrontendOpts();
  }

  HeaderSearchOptions &getHeaderSearchOpts() {
    return Invocation->getHeaderSearchOpts();
  }
  const HeaderSearchOptions &getHeaderSearchOpts() const {
    return Invocation->getHeaderSearchOpts();
  }
  std::shared_ptr<HeaderSearchOptions> getHeaderSearchOptsPtr() const {
    return Invocation->getHeaderSearchOptsPtr();
  }

  LangOptions &getLangOpts() {
    return *Invocation->getLangOpts();
  }
  const LangOptions &getLangOpts() const {
    return *Invocation->getLangOpts();
  }

  PreprocessorOptions &getPreprocessorOpts() {
    return Invocation->getPreprocessorOpts();
  }
  const PreprocessorOptions &getPreprocessorOpts() const {
    return Invocation->getPreprocessorOpts();
  }

  PreprocessorOutputOptions &getPreprocessorOutputOpts() {
    return Invocation->getPreprocessorOutputOpts();
  }
  const PreprocessorOutputOptions &getPreprocessorOutputOpts() const {
    return Invocation->getPreprocessorOutputOpts();
  }

  TargetOptions &getTargetOpts() {
    return Invocation->getTargetOpts();
  }
  const TargetOptions &getTargetOpts() const {
    return Invocation->getTargetOpts();
  }

  /// }
  /// @name Diagnostics Engine
  /// {

  bool hasDiagnostics() const { return Diagnostics != nullptr; }

  /// Get the current diagnostics engine.
  DiagnosticsEngine &getDiagnostics() const {
    assert(Diagnostics && "Compiler instance has no diagnostics!");
    return *Diagnostics;
  }

  /// setDiagnostics - Replace the current diagnostics engine.
  void setDiagnostics(DiagnosticsEngine *Value);

  DiagnosticConsumer &getDiagnosticClient() const {
    assert(Diagnostics && Diagnostics->getClient() &&
           "Compiler instance has no diagnostic client!");
    return *Diagnostics->getClient();
  }

  /// }
  /// @name VerboseOutputStream
  /// }

  /// Replace the current stream for verbose output.
  void setVerboseOutputStream(raw_ostream &Value);

  /// Replace the current stream for verbose output.
  void setVerboseOutputStream(std::unique_ptr<raw_ostream> Value);

  /// Get the current stream for verbose output.
  raw_ostream &getVerboseOutputStream() {
    return *VerboseOutputStream;
  }

  /// }
  /// @name Target Info
  /// {

  bool hasTarget() const { return Target != nullptr; }

  TargetInfo &getTarget() const {
    assert(Target && "Compiler instance has no target!");
    return *Target;
  }

  /// Replace the current Target.
  void setTarget(TargetInfo *Value);

  /// }
  /// @name AuxTarget Info
  /// {

  TargetInfo *getAuxTarget() const { return AuxTarget.get(); }

  /// Replace the current AuxTarget.
  void setAuxTarget(TargetInfo *Value);

  // Create Target and AuxTarget based on current options
  bool createTarget();

  /// }
  /// @name Virtual File System
  /// {

  llvm::vfs::FileSystem &getVirtualFileSystem() const;

  /// }
  /// @name File Manager
  /// {

  bool hasFileManager() const { return FileMgr != nullptr; }

  /// Return the current file manager to the caller.
  FileManager &getFileManager() const {
    assert(FileMgr && "Compiler instance has no file manager!");
    return *FileMgr;
  }

  void resetAndLeakFileManager() {
    llvm::BuryPointer(FileMgr.get());
    FileMgr.resetWithoutRelease();
  }

  /// Replace the current file manager and virtual file system.
  void setFileManager(FileManager *Value);

  /// }
  /// @name Source Manager
  /// {

  bool hasSourceManager() const { return SourceMgr != nullptr; }

  /// Return the current source manager.
  SourceManager &getSourceManager() const {
    assert(SourceMgr && "Compiler instance has no source manager!");
    return *SourceMgr;
  }

  void resetAndLeakSourceManager() {
    llvm::BuryPointer(SourceMgr.get());
    SourceMgr.resetWithoutRelease();
  }

  /// setSourceManager - Replace the current source manager.
  void setSourceManager(SourceManager *Value);

  /// }
  /// @name Preprocessor
  /// {

  bool hasPreprocessor() const { return PP != nullptr; }

  /// Return the current preprocessor.
  Preprocessor &getPreprocessor() const {
    assert(PP && "Compiler instance has no preprocessor!");
    return *PP;
  }

  std::shared_ptr<Preprocessor> getPreprocessorPtr() { return PP; }

  void resetAndLeakPreprocessor() {
    llvm::BuryPointer(new std::shared_ptr<Preprocessor>(PP));
  }

  /// Replace the current preprocessor.
  void setPreprocessor(std::shared_ptr<Preprocessor> Value);

  /// }
  /// @name ASTContext
  /// {

  bool hasASTContext() const { return Context != nullptr; }

  ASTContext &getASTContext() const {
    assert(Context && "Compiler instance has no AST context!");
    return *Context;
  }

  void resetAndLeakASTContext() {
    llvm::BuryPointer(Context.get());
    Context.resetWithoutRelease();
  }

  /// setASTContext - Replace the current AST context.
  void setASTContext(ASTContext *Value);

  /// Replace the current Sema; the compiler instance takes ownership
  /// of S.
  void setSema(Sema *S);

  /// }
  /// @name ASTConsumer
  /// {

  bool hasASTConsumer() const { return (bool)Consumer; }

  ASTConsumer &getASTConsumer() const {
    assert(Consumer && "Compiler instance has no AST consumer!");
    return *Consumer;
  }

  /// takeASTConsumer - Remove the current AST consumer and give ownership to
  /// the caller.
  std::unique_ptr<ASTConsumer> takeASTConsumer() { return std::move(Consumer); }

  /// setASTConsumer - Replace the current AST consumer; the compiler instance
  /// takes ownership of \p Value.
  void setASTConsumer(std::unique_ptr<ASTConsumer> Value);

  /// }
  /// @name Semantic analysis
  /// {
  bool hasSema() const { return (bool)TheSema; }

  Sema &getSema() const {
    assert(TheSema && "Compiler instance has no Sema object!");
    return *TheSema;
  }

  std::unique_ptr<Sema> takeSema();
  void resetAndLeakSema();

  /// }
  /// @name Module Management
  /// {

  IntrusiveRefCntPtr<ASTReader> getASTReader() const;
  void setASTReader(IntrusiveRefCntPtr<ASTReader> Reader);

  std::shared_ptr<ModuleDependencyCollector> getModuleDepCollector() const;
  void setModuleDepCollector(
      std::shared_ptr<ModuleDependencyCollector> Collector);

  std::shared_ptr<PCHContainerOperations> getPCHContainerOperations() const {
    return ThePCHContainerOperations;
  }

  /// Return the appropriate PCHContainerWriter depending on the
  /// current CodeGenOptions.
  const PCHContainerWriter &getPCHContainerWriter() const {
    assert(Invocation && "cannot determine module format without invocation");
    StringRef Format = getHeaderSearchOpts().ModuleFormat;
    auto *Writer = ThePCHContainerOperations->getWriterOrNull(Format);
    if (!Writer) {
      if (Diagnostics)
        Diagnostics->Report(diag::err_module_format_unhandled) << Format;
      llvm::report_fatal_error("unknown module format");
    }
    return *Writer;
  }

  /// Return the appropriate PCHContainerReader depending on the
  /// current CodeGenOptions.
  const PCHContainerReader &getPCHContainerReader() const {
    assert(Invocation && "cannot determine module format without invocation");
    StringRef Format = getHeaderSearchOpts().ModuleFormat;
    auto *Reader = ThePCHContainerOperations->getReaderOrNull(Format);
    if (!Reader) {
      if (Diagnostics)
        Diagnostics->Report(diag::err_module_format_unhandled) << Format;
      llvm::report_fatal_error("unknown module format");
    }
    return *Reader;
  }

  /// }
  /// @name Code Completion
  /// {

  bool hasCodeCompletionConsumer() const { return (bool)CompletionConsumer; }

  CodeCompleteConsumer &getCodeCompletionConsumer() const {
    assert(CompletionConsumer &&
           "Compiler instance has no code completion consumer!");
    return *CompletionConsumer;
  }

  /// setCodeCompletionConsumer - Replace the current code completion consumer;
  /// the compiler instance takes ownership of \p Value.
  void setCodeCompletionConsumer(CodeCompleteConsumer *Value);

  /// }
  /// @name Frontend timer
  /// {

  bool hasFrontendTimer() const { return (bool)FrontendTimer; }

  llvm::Timer &getFrontendTimer() const {
    assert(FrontendTimer && "Compiler instance has no frontend timer!");
    return *FrontendTimer;
  }

  /// }
  /// @name Output Files
  /// {

  /// clearOutputFiles - Clear the output file list. The underlying output
  /// streams must have been closed beforehand.
  ///
  /// \param EraseFiles - If true, attempt to erase the files from disk.
  void clearOutputFiles(bool EraseFiles);

  /// }
  /// @name Construction Utility Methods
  /// {

  /// Create the diagnostics engine using the invocation's diagnostic options
  /// and replace any existing one with it.
  ///
  /// Note that this routine also replaces the diagnostic client,
  /// allocating one if one is not provided.
  ///
  /// \param Client If non-NULL, a diagnostic client that will be
  /// attached to (and, then, owned by) the DiagnosticsEngine inside this AST
  /// unit.
  ///
  /// \param ShouldOwnClient If Client is non-NULL, specifies whether
  /// the diagnostic object should take ownership of the client.
  void createDiagnostics(DiagnosticConsumer *Client = nullptr,
                         bool ShouldOwnClient = true);

  /// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter.
  ///
  /// If no diagnostic client is provided, this creates a
  /// DiagnosticConsumer that is owned by the returned diagnostic
  /// object, if using directly the caller is responsible for
  /// releasing the returned DiagnosticsEngine's client eventually.
  ///
  /// \param Opts - The diagnostic options; note that the created text
  /// diagnostic object contains a reference to these options.
  ///
  /// \param Client If non-NULL, a diagnostic client that will be
  /// attached to (and, then, owned by) the returned DiagnosticsEngine
  /// object.
  ///
  /// \param CodeGenOpts If non-NULL, the code gen options in use, which may be
  /// used by some diagnostics printers (for logging purposes only).
  ///
  /// \return The new object on success, or null on failure.
  static IntrusiveRefCntPtr<DiagnosticsEngine>
  createDiagnostics(DiagnosticOptions *Opts,
                    DiagnosticConsumer *Client = nullptr,
                    bool ShouldOwnClient = true,
                    const CodeGenOptions *CodeGenOpts = nullptr);

  /// Create the file manager and replace any existing one with it.
  ///
  /// \return The new file manager on success, or null on failure.
  FileManager *
  createFileManager(IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr);

  /// Create the source manager and replace any existing one with it.
  void createSourceManager(FileManager &FileMgr);

  /// Create the preprocessor, using the invocation, file, and source managers,
  /// and replace any existing one with it.
  void createPreprocessor(TranslationUnitKind TUKind);

  std::string getSpecificModuleCachePath(StringRef ModuleHash);
  std::string getSpecificModuleCachePath() {
    return getSpecificModuleCachePath(getInvocation().getModuleHash());
  }

  /// Create the AST context.
  void createASTContext();

  /// Create an external AST source to read a PCH file and attach it to the AST
  /// context.
  void createPCHExternalASTSource(
      StringRef Path, DisableValidationForModuleKind DisableValidation,
      bool AllowPCHWithCompilerErrors, void *DeserializationListener,
      bool OwnDeserializationListener);

  /// Create an external AST source to read a PCH file.
  ///
  /// \return - The new object on success, or null on failure.
  static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource(
      StringRef Path, StringRef Sysroot,
      DisableValidationForModuleKind DisableValidation,
      bool AllowPCHWithCompilerErrors, Preprocessor &PP,
      InMemoryModuleCache &ModuleCache, ASTContext &Context,
      const PCHContainerReader &PCHContainerRdr,
      ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
      ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
      void *DeserializationListener, bool OwnDeserializationListener,
      bool Preamble, bool UseGlobalModuleIndex);

  /// Create a code completion consumer using the invocation; note that this
  /// will cause the source manager to truncate the input source file at the
  /// completion point.
  void createCodeCompletionConsumer();

  /// Create a code completion consumer to print code completion results, at
  /// \p Filename, \p Line, and \p Column, to the given output stream \p OS.
  static CodeCompleteConsumer *createCodeCompletionConsumer(
      Preprocessor &PP, StringRef Filename, unsigned Line, unsigned Column,
      const CodeCompleteOptions &Opts, raw_ostream &OS);

  /// Create the Sema object to be used for parsing.
  void createSema(TranslationUnitKind TUKind,
                  CodeCompleteConsumer *CompletionConsumer);

  /// Create the frontend timer and replace any existing one with it.
  void createFrontendTimer();

  /// Create the default output file (from the invocation's options) and add it
  /// to the list of tracked output files.
  ///
  /// The files created by this are usually removed on signal, and, depending
  /// on FrontendOptions, may also use a temporary file (that is, the data is
  /// written to a temporary file which will atomically replace the target
  /// output on success).
  ///
  /// \return - Null on error.
  std::unique_ptr<raw_pwrite_stream> createDefaultOutputFile(
      bool Binary = true, StringRef BaseInput = "", StringRef Extension = "",
      bool RemoveFileOnSignal = true, bool CreateMissingDirectories = false,
      bool ForceUseTemporary = false);

  /// Create a new output file, optionally deriving the output path name, and
  /// add it to the list of tracked output files.
  ///
  /// \return - Null on error.
  std::unique_ptr<raw_pwrite_stream>
  createOutputFile(StringRef OutputPath, bool Binary, bool RemoveFileOnSignal,
                   bool UseTemporary, bool CreateMissingDirectories = false);

private:
  /// Create a new output file and add it to the list of tracked output files.
  ///
  /// If \p OutputPath is empty, then createOutputFile will derive an output
  /// path location as \p BaseInput, with any suffix removed, and \p Extension
  /// appended. If \p OutputPath is not stdout and \p UseTemporary
  /// is true, createOutputFile will create a new temporary file that must be
  /// renamed to \p OutputPath in the end.
  ///
  /// \param OutputPath - If given, the path to the output file.
  /// \param Binary - The mode to open the file in.
  /// \param RemoveFileOnSignal - Whether the file should be registered with
  /// llvm::sys::RemoveFileOnSignal. Note that this is not safe for
  /// multithreaded use, as the underlying signal mechanism is not reentrant
  /// \param UseTemporary - Create a new temporary file that must be renamed to
  /// OutputPath in the end.
  /// \param CreateMissingDirectories - When \p UseTemporary is true, create
  /// missing directories in the output path.
  Expected<std::unique_ptr<raw_pwrite_stream>>
  createOutputFileImpl(StringRef OutputPath, bool Binary,
                       bool RemoveFileOnSignal, bool UseTemporary,
                       bool CreateMissingDirectories);

public:
  std::unique_ptr<raw_pwrite_stream> createNullOutputFile();

  /// }
  /// @name Initialization Utility Methods
  /// {

  /// InitializeSourceManager - Initialize the source manager to set InputFile
  /// as the main file.
  ///
  /// \return True on success.
  bool InitializeSourceManager(const FrontendInputFile &Input);

  /// InitializeSourceManager - Initialize the source manager to set InputFile
  /// as the main file.
  ///
  /// \return True on success.
  static bool InitializeSourceManager(const FrontendInputFile &Input,
                                      DiagnosticsEngine &Diags,
                                      FileManager &FileMgr,
                                      SourceManager &SourceMgr);

  /// }

  void setOutputStream(std::unique_ptr<llvm::raw_pwrite_stream> OutStream) {
    OutputStream = std::move(OutStream);
  }

  std::unique_ptr<llvm::raw_pwrite_stream> takeOutputStream() {
    return std::move(OutputStream);
  }

  void createASTReader();

  bool loadModuleFile(StringRef FileName);

private:
  /// Find a module, potentially compiling it, before reading its AST.  This is
  /// the guts of loadModule.
  ///
  /// For prebuilt modules, the Module is not expected to exist in
  /// HeaderSearch's ModuleMap.  If a ModuleFile by that name is in the
  /// ModuleManager, then it will be loaded and looked up.
  ///
  /// For implicit modules, the Module is expected to already be in the
  /// ModuleMap.  First attempt to load it from the given path on disk.  If that
  /// fails, defer to compileModuleAndReadAST, which will first build and then
  /// load it.
  ModuleLoadResult findOrCompileModuleAndReadAST(StringRef ModuleName,
                                                 SourceLocation ImportLoc,
                                                 SourceLocation ModuleNameLoc,
                                                 bool IsInclusionDirective);

public:
  ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
                              Module::NameVisibilityKind Visibility,
                              bool IsInclusionDirective) override;

  void createModuleFromSource(SourceLocation ImportLoc, StringRef ModuleName,
                              StringRef Source) override;

  void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility,
                         SourceLocation ImportLoc) override;

  bool hadModuleLoaderFatalFailure() const {
    return ModuleLoader::HadFatalFailure;
  }

  GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override;

  bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override;

  void addDependencyCollector(std::shared_ptr<DependencyCollector> Listener) {
    DependencyCollectors.push_back(std::move(Listener));
  }

  void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS);

  InMemoryModuleCache &getModuleCache() const { return *ModuleCache; }
};

} // end namespace clang

#endif
