//===--- Frontend.cpp - frontend utility methods --------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file contains utility methods for parsing and performing semantic
// on modules.
//
//===----------------------------------------------------------------------===//

#include "swift/Frontend/Frontend.h"
#include "swift/Subsystems.h"
#include "swift/Strings.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/DiagnosticsFrontend.h"
#include "swift/AST/DiagnosticsSema.h"
#include "swift/AST/Module.h"
#include "swift/Basic/SourceManager.h"
#include "swift/Parse/DelayedParsingCallbacks.h"
#include "swift/Parse/Lexer.h"
#include "swift/SIL/SILModule.h"
#include "swift/Serialization/SerializedModuleLoader.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"

using namespace swift;

std::string CompilerInvocation::getPCHHash() const {
  using llvm::hash_code;
  using llvm::hash_value;
  using llvm::hash_combine;

  auto Code = hash_value(LangOpts.getPCHHashComponents());
  Code = hash_combine(Code, FrontendOpts.getPCHHashComponents());
  Code = hash_combine(Code, ClangImporterOpts.getPCHHashComponents());
  Code = hash_combine(Code, SearchPathOpts.getPCHHashComponents());
  Code = hash_combine(Code, DiagnosticOpts.getPCHHashComponents());
  Code = hash_combine(Code, SILOpts.getPCHHashComponents());
  Code = hash_combine(Code, IRGenOpts.getPCHHashComponents());

  return llvm::APInt(64, Code).toString(36, /*Signed=*/false);
}

void CompilerInstance::createSILModule(bool WholeModule) {
  assert(MainModule && "main module not created yet");
  TheSILModule = SILModule::createEmptyModule(
    getMainModule(), Invocation.getSILOptions(), WholeModule);
}

void CompilerInstance::setPrimarySourceFile(SourceFile *SF) {
  assert(SF);
  assert(MainModule && "main module not created yet");
  assert(!PrimarySourceFile && "already has a primary source file");
  assert(PrimaryBufferID == NO_SUCH_BUFFER || !SF->getBufferID().hasValue() ||
         SF->getBufferID().getValue() == PrimaryBufferID);
  PrimarySourceFile = SF;
  PrimarySourceFile->setReferencedNameTracker(NameTracker);
}

bool CompilerInstance::setup(const CompilerInvocation &Invok) {
  Invocation = Invok;

  // Honor -Xllvm.
  if (!Invok.getFrontendOptions().LLVMArgs.empty()) {
    llvm::SmallVector<const char *, 4> Args;
    Args.push_back("swift (LLVM option parsing)");
    for (unsigned i = 0, e = Invok.getFrontendOptions().LLVMArgs.size(); i != e;
         ++i)
      Args.push_back(Invok.getFrontendOptions().LLVMArgs[i].c_str());
    Args.push_back(nullptr);
    llvm::cl::ParseCommandLineOptions(Args.size()-1, Args.data());
  }

  if (Invocation.getDiagnosticOptions().ShowDiagnosticsAfterFatalError) {
    Diagnostics.setShowDiagnosticsAfterFatalError();
  }
  if (Invocation.getDiagnosticOptions().SuppressWarnings) {
    Diagnostics.setSuppressWarnings(true);
  }
  if (Invocation.getDiagnosticOptions().WarningsAsErrors) {
    Diagnostics.setWarningsAsErrors(true);
  }

  // If we are asked to emit a module documentation file, configure lexing and
  // parsing to remember comments.
  if (!Invocation.getFrontendOptions().ModuleDocOutputPath.empty())
    Invocation.getLangOptions().AttachCommentsToDecls = true;

  Context.reset(new ASTContext(Invocation.getLangOptions(),
                               Invocation.getSearchPathOptions(),
                               SourceMgr, Diagnostics));

  if (Invocation.getFrontendOptions().EnableSourceImport) {
    bool immediate = Invocation.getFrontendOptions().actionIsImmediate();
    bool enableResilience = Invocation.getFrontendOptions().EnableResilience;
    Context->addModuleLoader(SourceLoader::create(*Context,
                                                  !immediate,
                                                  enableResilience,
                                                  DepTracker));
  }
  
  auto SML = SerializedModuleLoader::create(*Context, DepTracker);
  this->SML = SML.get();
  Context->addModuleLoader(std::move(SML));

  // Wire up the Clang importer. If the user has specified an SDK, use it.
  // Otherwise, we just keep it around as our interface to Clang's ABI
  // knowledge.
  auto clangImporter =
    ClangImporter::create(*Context, Invocation.getClangImporterOptions(),
                          Invocation.getPCHHash(),
                          DepTracker);
  if (!clangImporter) {
    Diagnostics.diagnose(SourceLoc(), diag::error_clang_importer_create_fail);
    return true;
  }

  Context->addModuleLoader(std::move(clangImporter), /*isClang*/true);

  assert(Lexer::isIdentifier(Invocation.getModuleName()));

  Optional<unsigned> CodeCompletionBufferID;
  auto CodeCompletePoint = Invocation.getCodeCompletionPoint();
  if (CodeCompletePoint.first) {
    auto MemBuf = CodeCompletePoint.first;
    // CompilerInvocation doesn't own the buffers, copy to a new buffer.
    CodeCompletionBufferID = SourceMgr.addMemBufferCopy(MemBuf);
    BufferIDs.push_back(*CodeCompletionBufferID);
    SourceMgr.setCodeCompletionPoint(*CodeCompletionBufferID,
                                     CodeCompletePoint.second);
  }

  bool MainMode = (Invocation.getInputKind() == InputFileKind::IFK_Swift);
  bool SILMode = (Invocation.getInputKind() == InputFileKind::IFK_SIL);

  if (SILMode)
    Invocation.getLangOptions().EnableAccessControl = false;

  const Optional<SelectedInput> &PrimaryInput =
    Invocation.getFrontendOptions().PrimaryInput;

  // Add the memory buffers first, these will be associated with a filename
  // and they can replace the contents of an input filename.
  for (unsigned i = 0, e = Invocation.getInputBuffers().size(); i != e; ++i) {
    // CompilerInvocation doesn't own the buffers, copy to a new buffer.
    auto *InputBuffer = Invocation.getInputBuffers()[i];
    auto Copy = std::unique_ptr<llvm::MemoryBuffer>(
        llvm::MemoryBuffer::getMemBufferCopy(
            InputBuffer->getBuffer(), InputBuffer->getBufferIdentifier()));
    if (serialization::isSerializedAST(Copy->getBuffer())) {
      PartialModules.push_back({ std::move(Copy), nullptr });
    } else {
      unsigned BufferID = SourceMgr.addNewSourceBuffer(std::move(Copy));
      BufferIDs.push_back(BufferID);

      if (SILMode)
        MainBufferID = BufferID;

      if (PrimaryInput && PrimaryInput->isBuffer() && PrimaryInput->Index == i)
        PrimaryBufferID = BufferID;
    }
  }

  for (unsigned i = 0, e = Invocation.getInputFilenames().size(); i != e; ++i) {
    auto &File = Invocation.getInputFilenames()[i];

    // FIXME: Working with filenames is fragile, maybe use the real path
    // or have some kind of FileManager.
    using namespace llvm::sys::path;
    if (Optional<unsigned> ExistingBufferID =
            SourceMgr.getIDForBufferIdentifier(File)) {
      if (SILMode || (MainMode && filename(File) == "main.swift"))
        MainBufferID = ExistingBufferID.getValue();

      if (PrimaryInput && PrimaryInput->isFilename() &&
          PrimaryInput->Index == i)
        PrimaryBufferID = ExistingBufferID.getValue();

      continue; // replaced by a memory buffer.
    }

    // Open the input file.
    using FileOrError = llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>;
    FileOrError InputFileOrErr = llvm::MemoryBuffer::getFileOrSTDIN(File);
    if (!InputFileOrErr) {
      Diagnostics.diagnose(SourceLoc(), diag::error_open_input_file,
                           File, InputFileOrErr.getError().message());
      return true;
    }

    if (serialization::isSerializedAST(InputFileOrErr.get()->getBuffer())) {
      llvm::SmallString<128> ModuleDocFilePath(File);
      llvm::sys::path::replace_extension(ModuleDocFilePath,
                                         SERIALIZED_MODULE_DOC_EXTENSION);
      FileOrError ModuleDocOrErr =
        llvm::MemoryBuffer::getFileOrSTDIN(ModuleDocFilePath.str());
      if (!ModuleDocOrErr &&
          ModuleDocOrErr.getError() != std::errc::no_such_file_or_directory) {
        Diagnostics.diagnose(SourceLoc(), diag::error_open_input_file,
                             File, ModuleDocOrErr.getError().message());
        return true;
      }
      PartialModules.push_back({ std::move(InputFileOrErr.get()),
                                 ModuleDocOrErr? std::move(ModuleDocOrErr.get())
                                               : nullptr });
      continue;
    }

    // Transfer ownership of the MemoryBuffer to the SourceMgr.
    unsigned BufferID =
      SourceMgr.addNewSourceBuffer(std::move(InputFileOrErr.get()));

    BufferIDs.push_back(BufferID);

    if (SILMode || (MainMode && filename(File) == "main.swift"))
      MainBufferID = BufferID;

    if (PrimaryInput && PrimaryInput->isFilename() && PrimaryInput->Index == i)
      PrimaryBufferID = BufferID;
  }

  // Set the primary file to the code-completion point if one exists.
  if (CodeCompletionBufferID.hasValue())
    PrimaryBufferID = *CodeCompletionBufferID;

  if (MainMode && MainBufferID == NO_SUCH_BUFFER && BufferIDs.size() == 1)
    MainBufferID = BufferIDs.front();

  return false;
}

ModuleDecl *CompilerInstance::getMainModule() {
  if (!MainModule) {
    Identifier ID = Context->getIdentifier(Invocation.getModuleName());
    MainModule = ModuleDecl::create(ID, *Context);
    if (Invocation.getFrontendOptions().EnableTesting)
      MainModule->setTestingEnabled();

    if (Invocation.getFrontendOptions().EnableResilience)
      MainModule->setResilienceStrategy(ResilienceStrategy::Resilient);
    else if (Invocation.getSILOptions().SILSerializeAll)
      MainModule->setResilienceStrategy(ResilienceStrategy::Fragile);
  }
  return MainModule;
}

void CompilerInstance::performSema() {
  const FrontendOptions &options = Invocation.getFrontendOptions();
  const InputFileKind Kind = Invocation.getInputKind();
  ModuleDecl *MainModule = getMainModule();
  Context->LoadedModules[MainModule->getName()] = MainModule;

  auto modImpKind = SourceFile::ImplicitModuleImportKind::Stdlib;

  if (Kind == InputFileKind::IFK_SIL) {
    assert(BufferIDs.size() == 1);
    assert(MainBufferID != NO_SUCH_BUFFER);
    // Assume WMO, if a -primary-file option was not provided.
    createSILModule(!options.PrimaryInput.hasValue());
    modImpKind = SourceFile::ImplicitModuleImportKind::None;
  } else if (Invocation.getParseStdlib()) {
    modImpKind = SourceFile::ImplicitModuleImportKind::Builtin;
  }

  switch (modImpKind) {
  case SourceFile::ImplicitModuleImportKind::None:
  case SourceFile::ImplicitModuleImportKind::Builtin:
    break;
  case SourceFile::ImplicitModuleImportKind::Stdlib: {
    ModuleDecl *M = Context->getStdlibModule(true);

    if (!M) {
      Diagnostics.diagnose(SourceLoc(), diag::error_stdlib_not_found,
                           Invocation.getTargetTriple());
      return;
    }

    // If we failed to load, we should have already diagnosed
    if (M->failedToLoad()) {
      assert(Diagnostics.hadAnyError() &&
             "Module failed to load but nothing was diagnosed?");
      return;
    }

    const auto &silOptions = Invocation.getSILOptions();
    if ((silOptions.Optimization <= SILOptions::SILOptMode::None &&
         (options.RequestedAction == FrontendOptions::EmitObject ||
          options.RequestedAction == FrontendOptions::Immediate ||
          options.RequestedAction == FrontendOptions::EmitSIL)) ||
        (silOptions.Optimization == SILOptions::SILOptMode::None &&
         options.RequestedAction >= FrontendOptions::EmitSILGen)) {
      // Implicitly import the SwiftOnoneSupport module in non-optimized
      // builds. This allows for use of popular specialized functions
      // from the standard library, which makes the non-optimized builds
      // execute much faster.
      Invocation.getFrontendOptions()
                .ImplicitImportModuleNames.push_back(SWIFT_ONONE_SUPPORT);
    }
    break;
  }
  }

  auto clangImporter =
    static_cast<ClangImporter *>(Context->getClangModuleLoader());

  ModuleDecl *underlying = nullptr;
  if (options.ImportUnderlyingModule) {
    underlying = clangImporter->loadModule(SourceLoc(),
                                           std::make_pair(MainModule->getName(),
                                                          SourceLoc()));
    if (!underlying) {
      Diagnostics.diagnose(SourceLoc(), diag::error_underlying_module_not_found,
                           MainModule->getName());
    }
  }

  ModuleDecl *importedHeaderModule = nullptr;
  StringRef implicitHeaderPath = options.ImplicitObjCHeaderPath;
  if (!implicitHeaderPath.empty()) {
    if (!clangImporter->importBridgingHeader(implicitHeaderPath, MainModule)) {
      importedHeaderModule = clangImporter->getImportedHeaderModule();
      assert(importedHeaderModule);
    }
  }

  SmallVector<ModuleDecl *, 4> importModules;
  if (!options.ImplicitImportModuleNames.empty()) {
    for (auto &ImplicitImportModuleName : options.ImplicitImportModuleNames) {
      if (Lexer::isIdentifier(ImplicitImportModuleName)) {
        auto moduleID = Context->getIdentifier(ImplicitImportModuleName);
        ModuleDecl *importModule = Context->getModule(std::make_pair(moduleID,
                                                                 SourceLoc()));
        if (importModule) {
          importModules.push_back(importModule);
        } else {
          Diagnostics.diagnose(SourceLoc(), diag::sema_no_import,
                               ImplicitImportModuleName);
          if (Invocation.getSearchPathOptions().SDKPath.empty() &&
              llvm::Triple(llvm::sys::getProcessTriple()).isMacOSX()) {
            Diagnostics.diagnose(SourceLoc(), diag::sema_no_import_no_sdk);
            Diagnostics.diagnose(SourceLoc(),
                                 diag::sema_no_import_no_sdk_xcrun);
          }
        }
      } else {
        Diagnostics.diagnose(SourceLoc(), diag::error_bad_module_name,
                             ImplicitImportModuleName, false);
      }
    }
  }

  auto addAdditionalInitialImports = [&](SourceFile *SF) {
    if (!underlying && !importedHeaderModule && importModules.empty())
      return;

    using ImportPair =
        std::pair<ModuleDecl::ImportedModule, SourceFile::ImportOptions>;
    SmallVector<ImportPair, 4> additionalImports;

    if (underlying)
      additionalImports.push_back({ { /*accessPath=*/{}, underlying },
                                    SourceFile::ImportFlags::Exported });
    if (importedHeaderModule)
      additionalImports.push_back({ { /*accessPath=*/{}, importedHeaderModule },
                                    SourceFile::ImportFlags::Exported });
    if (!importModules.empty()) {
      for (auto &importModule : importModules) {
        additionalImports.push_back({ { /*accessPath=*/{}, importModule }, {} });
      }
    }

    SF->addImports(additionalImports);
  };

  if (Kind == InputFileKind::IFK_Swift_REPL) {
    auto *SingleInputFile =
      new (*Context) SourceFile(*MainModule, Invocation.getSourceFileKind(),
                                None, modImpKind);
    MainModule->addFile(*SingleInputFile);
    addAdditionalInitialImports(SingleInputFile);
    return;
  }

  std::unique_ptr<DelayedParsingCallbacks> DelayedCB;
  if (Invocation.isCodeCompletion()) {
    DelayedCB.reset(
        new CodeCompleteDelayedCallbacks(SourceMgr.getCodeCompletionLoc()));
  } else if (Invocation.isDelayedFunctionBodyParsing()) {
    DelayedCB.reset(new AlwaysDelayedCallbacks);
  }

  PersistentParserState PersistentState;

  // Make sure the main file is the first file in the module. This may only be
  // a source file, or it may be a SIL file, which requires pumping the parser.
  // We parse it last, though, to make sure that it can use decls from other
  // files in the module.
  if (MainBufferID != NO_SUCH_BUFFER) {
    assert(Kind == InputFileKind::IFK_Swift || Kind == InputFileKind::IFK_SIL);

    if (Kind == InputFileKind::IFK_Swift)
      SourceMgr.setHashbangBufferID(MainBufferID);

    auto *MainFile = new (*Context) SourceFile(*MainModule,
                                               Invocation.getSourceFileKind(),
                                               MainBufferID, modImpKind);
    MainModule->addFile(*MainFile);
    addAdditionalInitialImports(MainFile);

    if (MainBufferID == PrimaryBufferID)
      setPrimarySourceFile(MainFile);
  }

  bool hadLoadError = false;

  // Parse all the partial modules first.
  for (auto &PM : PartialModules) {
    assert(PM.ModuleBuffer);
    if (!SML->loadAST(*MainModule, SourceLoc(), std::move(PM.ModuleBuffer),
                      std::move(PM.ModuleDocBuffer)))
      hadLoadError = true;
  }

  // Then parse all the library files.
  for (auto BufferID : BufferIDs) {
    if (BufferID == MainBufferID)
      continue;

    auto *NextInput = new (*Context) SourceFile(*MainModule,
                                                SourceFileKind::Library,
                                                BufferID,
                                                modImpKind);
    MainModule->addFile(*NextInput);
    addAdditionalInitialImports(NextInput);

    if (BufferID == PrimaryBufferID)
      setPrimarySourceFile(NextInput);

    auto &Diags = NextInput->getASTContext().Diags;
    auto DidSuppressWarnings = Diags.getSuppressWarnings();
    auto IsPrimary
      = PrimaryBufferID == NO_SUCH_BUFFER || BufferID == PrimaryBufferID;
    Diags.setSuppressWarnings(DidSuppressWarnings || !IsPrimary);

    bool Done;
    do {
      // Parser may stop at some erroneous constructions like #else, #endif
      // or '}' in some cases, continue parsing until we are done
      parseIntoSourceFile(*NextInput, BufferID, &Done, nullptr,
                          &PersistentState, DelayedCB.get());
    } while (!Done);

    Diags.setSuppressWarnings(DidSuppressWarnings);

    performNameBinding(*NextInput);
  }

  if (Invocation.isCodeCompletion()) {
    // When we are doing code completion, make sure to emit at least one
    // diagnostic, so that ASTContext is marked as erroneous.  In this case
    // various parts of the compiler (for example, AST verifier) have less
    // strict assumptions about the AST.
    Diagnostics.diagnose(SourceLoc(), diag::error_doing_code_completion);
  }

  if (hadLoadError)
    return;

  // Compute the options we want to use for type checking.
  OptionSet<TypeCheckingFlags> TypeCheckOptions;
  if (PrimaryBufferID == NO_SUCH_BUFFER) {
    TypeCheckOptions |= TypeCheckingFlags::DelayWholeModuleChecking;
  }
  if (options.DebugTimeFunctionBodies) {
    TypeCheckOptions |= TypeCheckingFlags::DebugTimeFunctionBodies;
  }
  if (options.actionIsImmediate()) {
    TypeCheckOptions |= TypeCheckingFlags::ForImmediateMode;
  }
  if (options.DebugTimeExpressionTypeChecking) {
    TypeCheckOptions |= TypeCheckingFlags::DebugTimeExpressions;
  }

  // Parse the main file last.
  if (MainBufferID != NO_SUCH_BUFFER) {
    bool mainIsPrimary =
      (PrimaryBufferID == NO_SUCH_BUFFER || MainBufferID == PrimaryBufferID);

    SourceFile &MainFile =
      MainModule->getMainSourceFile(Invocation.getSourceFileKind());

    auto &Diags = MainFile.getASTContext().Diags;
    auto DidSuppressWarnings = Diags.getSuppressWarnings();
    Diags.setSuppressWarnings(DidSuppressWarnings || !mainIsPrimary);

    SILParserState SILContext(TheSILModule.get());
    unsigned CurTUElem = 0;
    bool Done;
    do {
      // Pump the parser multiple times if necessary.  It will return early
      // after parsing any top level code in a main module, or in SIL mode when
      // there are chunks of swift decls (e.g. imports and types) interspersed
      // with 'sil' definitions.
      parseIntoSourceFile(MainFile, MainFile.getBufferID().getValue(), &Done,
                          TheSILModule ? &SILContext : nullptr,
                          &PersistentState, DelayedCB.get());
      if (mainIsPrimary) {
        performTypeChecking(MainFile, PersistentState.getTopLevelContext(),
                            TypeCheckOptions, CurTUElem,
                            options.WarnLongFunctionBodies,
                            options.WarnLongExpressionTypeChecking,
                            options.SolverExpressionTimeThreshold);
      }
      CurTUElem = MainFile.Decls.size();
    } while (!Done);

    Diags.setSuppressWarnings(DidSuppressWarnings);
    
    if (mainIsPrimary && !Context->hadError() &&
        Invocation.getFrontendOptions().PCMacro) {
      performPCMacro(MainFile, PersistentState.getTopLevelContext());
    }
    
    // Playground transform knows to look out for PCMacro's changes and not
    // to playground log them.
    if (mainIsPrimary && !Context->hadError() &&
        Invocation.getFrontendOptions().PlaygroundTransform)
      performPlaygroundTransform(MainFile, Invocation.getFrontendOptions().PlaygroundHighPerformance);
    if (!mainIsPrimary) {
      performNameBinding(MainFile);
    }
  }

  // Type-check each top-level input besides the main source file.
  for (auto File : MainModule->getFiles())
    if (auto SF = dyn_cast<SourceFile>(File))
      if (PrimaryBufferID == NO_SUCH_BUFFER || SF == PrimarySourceFile)
        performTypeChecking(*SF, PersistentState.getTopLevelContext(),
                            TypeCheckOptions, /*curElem*/ 0,
                            options.WarnLongFunctionBodies,
                            options.WarnLongExpressionTypeChecking,
                            options.SolverExpressionTimeThreshold);

  // Even if there were no source files, we should still record known
  // protocols.
  if (auto *stdlib = Context->getStdlibModule())
    Context->recordKnownProtocols(stdlib);

  if (DelayedCB) {
    performDelayedParsing(MainModule, PersistentState,
                          Invocation.getCodeCompletionFactory());
  }

  // Perform whole-module type checking.
  if (TypeCheckOptions & TypeCheckingFlags::DelayWholeModuleChecking) {
    for (auto File : MainModule->getFiles())
      if (auto SF = dyn_cast<SourceFile>(File))
        performWholeModuleTypeChecking(*SF);
  }

  for (auto File : MainModule->getFiles())
    if (auto SF = dyn_cast<SourceFile>(File))
      if (PrimaryBufferID == NO_SUCH_BUFFER || SF == PrimarySourceFile)
        finishTypeChecking(*SF);
}

void CompilerInstance::performParseOnly() {
  const InputFileKind Kind = Invocation.getInputKind();
  ModuleDecl *MainModule = getMainModule();
  Context->LoadedModules[MainModule->getName()] = MainModule;

  assert((Kind == InputFileKind::IFK_Swift ||
          Kind == InputFileKind::IFK_Swift_Library) &&
         "only supports parsing .swift files");
  (void)Kind;

  auto modImpKind = SourceFile::ImplicitModuleImportKind::None;

  // Make sure the main file is the first file in the module but parse it last,
  // to match the parsing logic used when performing Sema.
  if (MainBufferID != NO_SUCH_BUFFER) {
    assert(Kind == InputFileKind::IFK_Swift);
    SourceMgr.setHashbangBufferID(MainBufferID);

    auto *MainFile = new (*Context) SourceFile(
        *MainModule, Invocation.getSourceFileKind(), MainBufferID, modImpKind);
    MainModule->addFile(*MainFile);

    if (MainBufferID == PrimaryBufferID)
      setPrimarySourceFile(MainFile);
  }

  PersistentParserState PersistentState;
  // Parse all the library files.
  for (auto BufferID : BufferIDs) {
    if (BufferID == MainBufferID)
      continue;

    auto *NextInput = new (*Context)
        SourceFile(*MainModule, SourceFileKind::Library, BufferID, modImpKind);
    MainModule->addFile(*NextInput);
    if (BufferID == PrimaryBufferID)
      setPrimarySourceFile(NextInput);

    bool Done;
    do {
      // Parser may stop at some erroneous constructions like #else, #endif
      // or '}' in some cases, continue parsing until we are done
      parseIntoSourceFile(*NextInput, BufferID, &Done, nullptr,
                          &PersistentState, nullptr);
    } while (!Done);
  }

  // Now parse the main file.
  if (MainBufferID != NO_SUCH_BUFFER) {
    SourceFile &MainFile =
        MainModule->getMainSourceFile(Invocation.getSourceFileKind());

    bool Done;
    do {
      parseIntoSourceFile(MainFile, MainFile.getBufferID().getValue(), &Done,
                          nullptr, &PersistentState, nullptr);
    } while (!Done);
  }

  assert(Context->LoadedModules.size() == 1 &&
         "Loaded a module during parse-only");
}

void CompilerInstance::freeContextAndSIL() {
  Context.reset();
  TheSILModule.reset();
  MainModule = nullptr;
  SML = nullptr;
  PrimarySourceFile = nullptr;
}
