Files
swift-mirror/include/swift/Frontend/Frontend.h
Hamish Knight d77cae6720 Move PersistentParserState onto SourceFile
Move the global PersistentParserState from
the CompilerInstance to the source file that code
completion is operating on, only hooking up the
state when it's needed. This will help make it
easier to requestify source file parsing.
2020-03-02 11:22:44 -08:00

710 lines
25 KiB
C++

//===--- Frontend.h - frontend utility methods ------------------*- C++ -*-===//
//
// 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 declarations of utility methods for parsing and
// performing semantic on modules.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_FRONTEND_H
#define SWIFT_FRONTEND_H
#include "swift/AST/DiagnosticConsumer.h"
#include "swift/AST/DiagnosticEngine.h"
#include "swift/AST/IRGenOptions.h"
#include "swift/AST/LinkLibrary.h"
#include "swift/AST/Module.h"
#include "swift/AST/SILOptions.h"
#include "swift/AST/SearchPathOptions.h"
#include "swift/AST/SourceFile.h"
#include "swift/Basic/DiagnosticOptions.h"
#include "swift/Basic/LangOptions.h"
#include "swift/Basic/SourceManager.h"
#include "swift/ClangImporter/ClangImporter.h"
#include "swift/ClangImporter/ClangImporterOptions.h"
#include "swift/Frontend/FrontendOptions.h"
#include "swift/Frontend/ModuleInterfaceSupport.h"
#include "swift/Migrator/MigratorOptions.h"
#include "swift/Parse/CodeCompletionCallbacks.h"
#include "swift/Parse/Parser.h"
#include "swift/Parse/SyntaxParsingCache.h"
#include "swift/Sema/SourceLoader.h"
#include "swift/Serialization/Validation.h"
#include "swift/Subsystems.h"
#include "swift/TBDGen/TBDGen.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/MemoryBuffer.h"
#include "clang/Basic/FileManager.h"
#include <memory>
namespace swift {
class SerializedModuleLoader;
class MemoryBufferSerializedModuleLoader;
class SILModule;
namespace Lowering {
class TypeConverter;
}
struct ModuleBuffers {
std::unique_ptr<llvm::MemoryBuffer> ModuleBuffer;
std::unique_ptr<llvm::MemoryBuffer> ModuleDocBuffer;
std::unique_ptr<llvm::MemoryBuffer> ModuleSourceInfoBuffer;
ModuleBuffers(std::unique_ptr<llvm::MemoryBuffer> ModuleBuffer,
std::unique_ptr<llvm::MemoryBuffer> ModuleDocBuffer = nullptr,
std::unique_ptr<llvm::MemoryBuffer> ModuleSourceInfoBuffer = nullptr):
ModuleBuffer(std::move(ModuleBuffer)),
ModuleDocBuffer(std::move(ModuleDocBuffer)),
ModuleSourceInfoBuffer(std::move(ModuleSourceInfoBuffer)) {}
};
/// The abstract configuration of the compiler, including:
/// - options for all stages of translation,
/// - information about the build environment,
/// - information about the job being performed, and
/// - lists of inputs and outputs.
///
/// A CompilerInvocation can be built from a frontend command line
/// using parseArgs. It can then be used to build a CompilerInstance,
/// which manages the actual compiler execution.
class CompilerInvocation {
LangOptions LangOpts;
TypeCheckerOptions TypeCheckerOpts;
FrontendOptions FrontendOpts;
ClangImporterOptions ClangImporterOpts;
SearchPathOptions SearchPathOpts;
DiagnosticOptions DiagnosticOpts;
MigratorOptions MigratorOpts;
SILOptions SILOpts;
IRGenOptions IRGenOpts;
TBDGenOptions TBDGenOpts;
ModuleInterfaceOptions ModuleInterfaceOpts;
/// The \c SyntaxParsingCache to use when parsing the main file of this
/// invocation
SyntaxParsingCache *MainFileSyntaxParsingCache = nullptr;
llvm::MemoryBuffer *CodeCompletionBuffer = nullptr;
/// Code completion offset in bytes from the beginning of the main
/// source file. Valid only if \c isCodeCompletion() == true.
unsigned CodeCompletionOffset = ~0U;
CodeCompletionCallbacksFactory *CodeCompletionFactory = nullptr;
public:
CompilerInvocation();
/// Initializes the compiler invocation for the list of arguments.
///
/// All parsing should be additive, i.e. options should not be reset to their
/// default values given the /absence/ of a flag. This is because \c parseArgs
/// may be used to modify an already partially configured invocation.
///
/// Any configuration files loaded as a result of parsing arguments will be
/// stored in \p ConfigurationFileBuffers, if non-null. The contents of these
/// buffers should \e not be interpreted by the caller; they are only present
/// in order to make it possible to reproduce how these arguments were parsed
/// if the compiler ends up crashing or exhibiting other bad behavior.
///
/// If non-empty, relative search paths are resolved relative to
/// \p workingDirectory.
///
/// \returns true if there was an error, false on success.
bool parseArgs(ArrayRef<const char *> Args, DiagnosticEngine &Diags,
SmallVectorImpl<std::unique_ptr<llvm::MemoryBuffer>>
*ConfigurationFileBuffers = nullptr,
StringRef workingDirectory = {});
/// Sets specific options based on the given serialized Swift binary data.
///
/// This is additive, i.e. options are not reset to their default values given
/// the /absence/ of a flag. However, flags that only have a single value may
/// (and should) be overwritten by this method.
///
/// Invoking this on more than one serialized AST is likely to result in
/// one or both of them failing to load. Please pick one AST to provide base
/// flags for the entire ASTContext and let the others succeed or fail the
/// normal way. (Some additive flags, like search paths, will be handled
/// properly during normal module loading.)
///
/// \returns Status::Valid on success, one of the Status issues on error.
serialization::Status loadFromSerializedAST(StringRef data);
/// Serialize the command line arguments for emitting them
/// to DWARF or CodeView and inject SDKPath if necessary.
static void buildDebugFlags(std::string &Output,
const ArrayRef<const char*> &Args,
StringRef SDKPath,
StringRef ResourceDir);
void setTargetTriple(const llvm::Triple &Triple);
void setTargetTriple(StringRef Triple);
StringRef getTargetTriple() const {
return LangOpts.Target.str();
}
void setClangModuleCachePath(StringRef Path) {
ClangImporterOpts.ModuleCachePath = Path.str();
}
StringRef getClangModuleCachePath() const {
return ClangImporterOpts.ModuleCachePath;
}
void setImportSearchPaths(const std::vector<std::string> &Paths) {
SearchPathOpts.ImportSearchPaths = Paths;
}
ArrayRef<std::string> getImportSearchPaths() const {
return SearchPathOpts.ImportSearchPaths;
}
void setFrameworkSearchPaths(
const std::vector<SearchPathOptions::FrameworkSearchPath> &Paths) {
SearchPathOpts.FrameworkSearchPaths = Paths;
}
ArrayRef<SearchPathOptions::FrameworkSearchPath> getFrameworkSearchPaths() const {
return SearchPathOpts.FrameworkSearchPaths;
}
void setExtraClangArgs(const std::vector<std::string> &Args) {
ClangImporterOpts.ExtraArgs = Args;
}
ArrayRef<std::string> getExtraClangArgs() const {
return ClangImporterOpts.ExtraArgs;
}
void addLinkLibrary(StringRef name, LibraryKind kind) {
IRGenOpts.LinkLibraries.push_back({name, kind});
}
ArrayRef<LinkLibrary> getLinkLibraries() const {
return IRGenOpts.LinkLibraries;
}
void setMainExecutablePath(StringRef Path);
void setRuntimeResourcePath(StringRef Path);
/// Computes the runtime resource path relative to the given Swift
/// executable.
static void computeRuntimeResourcePathFromExecutablePath(
StringRef mainExecutablePath,
llvm::SmallString<128> &runtimeResourcePath);
void setSDKPath(const std::string &Path);
StringRef getSDKPath() const {
return SearchPathOpts.SDKPath;
}
LangOptions &getLangOptions() {
return LangOpts;
}
const LangOptions &getLangOptions() const {
return LangOpts;
}
TypeCheckerOptions &getTypeCheckerOptions() { return TypeCheckerOpts; }
const TypeCheckerOptions &getTypeCheckerOptions() const {
return TypeCheckerOpts;
}
FrontendOptions &getFrontendOptions() { return FrontendOpts; }
const FrontendOptions &getFrontendOptions() const { return FrontendOpts; }
TBDGenOptions &getTBDGenOptions() { return TBDGenOpts; }
const TBDGenOptions &getTBDGenOptions() const { return TBDGenOpts; }
ModuleInterfaceOptions &getModuleInterfaceOptions() { return ModuleInterfaceOpts; }
const ModuleInterfaceOptions &getModuleInterfaceOptions() const { return ModuleInterfaceOpts; }
ClangImporterOptions &getClangImporterOptions() { return ClangImporterOpts; }
const ClangImporterOptions &getClangImporterOptions() const {
return ClangImporterOpts;
}
SearchPathOptions &getSearchPathOptions() { return SearchPathOpts; }
const SearchPathOptions &getSearchPathOptions() const {
return SearchPathOpts;
}
DiagnosticOptions &getDiagnosticOptions() { return DiagnosticOpts; }
const DiagnosticOptions &getDiagnosticOptions() const {
return DiagnosticOpts;
}
const MigratorOptions &getMigratorOptions() const {
return MigratorOpts;
}
SILOptions &getSILOptions() { return SILOpts; }
const SILOptions &getSILOptions() const { return SILOpts; }
IRGenOptions &getIRGenOptions() { return IRGenOpts; }
const IRGenOptions &getIRGenOptions() const { return IRGenOpts; }
void setMainFileSyntaxParsingCache(SyntaxParsingCache *Cache) {
MainFileSyntaxParsingCache = Cache;
}
SyntaxParsingCache *getMainFileSyntaxParsingCache() const {
return MainFileSyntaxParsingCache;
}
void setParseStdlib() {
FrontendOpts.ParseStdlib = true;
}
bool getParseStdlib() const {
return FrontendOpts.ParseStdlib;
}
void setInputKind(InputFileKind K) {
FrontendOpts.InputKind = K;
}
InputFileKind getInputKind() const {
return FrontendOpts.InputKind;
}
SourceFileKind getSourceFileKind() const;
void setModuleName(StringRef Name) {
FrontendOpts.ModuleName = Name.str();
IRGenOpts.ModuleName = Name.str();
}
StringRef getModuleName() const {
return FrontendOpts.ModuleName;
}
std::string getOutputFilename() const {
return FrontendOpts.InputsAndOutputs.getSingleOutputFilename();
}
void setCodeCompletionPoint(llvm::MemoryBuffer *Buf, unsigned Offset) {
assert(Buf);
CodeCompletionBuffer = Buf;
CodeCompletionOffset = Offset;
// We don't need typo-correction for code-completion.
// FIXME: This isn't really true, but is a performance issue.
LangOpts.TypoCorrectionLimit = 0;
}
std::pair<llvm::MemoryBuffer *, unsigned> getCodeCompletionPoint() const {
return std::make_pair(CodeCompletionBuffer, CodeCompletionOffset);
}
/// \returns true if we are doing code completion.
bool isCodeCompletion() const {
return CodeCompletionOffset != ~0U;
}
/// Called from lldb, see rdar://53971116
void disableASTScopeLookup() {
LangOpts.EnableASTScopeLookup = false;
}
/// Retrieve a module hash string that is suitable for uniquely
/// identifying the conditions under which the module was built, for use
/// in generating a cached PCH file for the bridging header.
std::string getPCHHash() const;
SourceFile::ImplicitModuleImportKind getImplicitModuleImportKind() const {
if (getInputKind() == InputFileKind::SIL) {
return SourceFile::ImplicitModuleImportKind::None;
}
if (getParseStdlib()) {
return SourceFile::ImplicitModuleImportKind::Builtin;
}
return SourceFile::ImplicitModuleImportKind::Stdlib;
}
/// Performs input setup common to these tools:
/// sil-opt, sil-func-extractor, sil-llvm-gen, and sil-nm.
/// Return value includes the buffer so caller can keep it alive.
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
setUpInputForSILTool(StringRef inputFilename, StringRef moduleNameArg,
bool alwaysSetModuleToMain, bool bePrimary,
serialization::ExtendedValidationInfo &extendedInfo);
bool hasSerializedAST() {
return FrontendOpts.InputKind == InputFileKind::SwiftLibrary;
}
const PrimarySpecificPaths &
getPrimarySpecificPathsForAtMostOnePrimary() const;
const PrimarySpecificPaths &
getPrimarySpecificPathsForPrimary(StringRef filename) const;
const PrimarySpecificPaths &
getPrimarySpecificPathsForSourceFile(const SourceFile &SF) const;
std::string getOutputFilenameForAtMostOnePrimary() const;
std::string getMainInputFilenameForDebugInfoForAtMostOnePrimary() const;
std::string getObjCHeaderOutputPathForAtMostOnePrimary() const;
std::string getModuleOutputPathForAtMostOnePrimary() const;
std::string
getReferenceDependenciesFilePathForPrimary(StringRef filename) const;
std::string getSwiftRangesFilePathForPrimary(StringRef filename) const;
std::string getCompiledSourceFilePathForPrimary(StringRef filename) const;
std::string getSerializedDiagnosticsPathForAtMostOnePrimary() const;
/// TBDPath only makes sense in whole module compilation mode,
/// so return the TBDPath when in that mode and fail an assert
/// if not in that mode.
std::string getTBDPathForWholeModule() const;
/// ModuleInterfaceOutputPath only makes sense in whole module compilation
/// mode, so return the ModuleInterfaceOutputPath when in that mode and
/// fail an assert if not in that mode.
std::string getModuleInterfaceOutputPathForWholeModule() const;
std::string getPrivateModuleInterfaceOutputPathForWholeModule() const;
std::string getLdAddCFileOutputPathForWholeModule() const;
SerializationOptions
computeSerializationOptions(const SupplementaryOutputPaths &outs,
bool moduleIsPublic) const;
};
/// A class which manages the state and execution of the compiler.
/// This owns the primary compiler singletons, such as the ASTContext,
/// as well as various build products such as the SILModule.
///
/// Before a CompilerInstance can be used, it must be configured by
/// calling \a setup. If successful, this will create an ASTContext
/// and set up the basic compiler invariants. Calling \a setup multiple
/// times on a single CompilerInstance is not permitted.
class CompilerInstance {
CompilerInvocation Invocation;
SourceManager SourceMgr;
DiagnosticEngine Diagnostics{SourceMgr};
std::unique_ptr<ASTContext> Context;
std::unique_ptr<Lowering::TypeConverter> TheSILTypes;
std::unique_ptr<SILModule> TheSILModule;
/// Null if no tracker.
std::unique_ptr<DependencyTracker> DepTracker;
/// If there is no stats output directory by the time the
/// instance has completed its setup, this will be null.
std::unique_ptr<UnifiedStatsReporter> Stats;
mutable ModuleDecl *MainModule = nullptr;
SerializedModuleLoader *SML = nullptr;
MemoryBufferSerializedModuleLoader *MemoryBufferLoader = nullptr;
/// Contains buffer IDs for input source code files.
std::vector<unsigned> InputSourceCodeBufferIDs;
/// Contains \c MemoryBuffers for partial serialized module files and
/// corresponding partial serialized module documentation files.
std::vector<ModuleBuffers> PartialModules;
enum : unsigned { NO_SUCH_BUFFER = ~0U };
unsigned MainBufferID = NO_SUCH_BUFFER;
/// Identifies the set of input buffers in the SourceManager that are
/// considered primaries.
llvm::SetVector<unsigned> PrimaryBufferIDs;
/// Identifies the set of SourceFiles that are considered primaries. An
/// invariant is that any SourceFile in this set with an associated
/// buffer will also have its buffer ID in PrimaryBufferIDs.
std::vector<SourceFile *> PrimarySourceFiles;
/// The file that has been registered for code completion.
NullablePtr<SourceFile> CodeCompletionFile;
/// Return whether there is an entry in PrimaryInputs for buffer \p BufID.
bool isPrimaryInput(unsigned BufID) const {
return PrimaryBufferIDs.count(BufID) != 0;
}
/// Record in PrimaryBufferIDs the fact that \p BufID is a primary.
/// If \p BufID is already in the set, do nothing.
void recordPrimaryInputBuffer(unsigned BufID);
/// Record in PrimarySourceFiles the fact that \p SF is a primary, and
/// call recordPrimaryInputBuffer on \p SF's buffer (if it exists).
void recordPrimarySourceFile(SourceFile *SF);
bool isWholeModuleCompilation() { return PrimaryBufferIDs.empty(); }
public:
// Out of line to avoid having to import SILModule.h.
CompilerInstance();
~CompilerInstance();
CompilerInstance(const CompilerInstance &) = delete;
void operator=(const CompilerInstance &) = delete;
CompilerInstance(CompilerInstance &&) = delete;
void operator=(CompilerInstance &&) = delete;
SourceManager &getSourceMgr() { return SourceMgr; }
const SourceManager &getSourceMgr() const { return SourceMgr; }
DiagnosticEngine &getDiags() { return Diagnostics; }
const DiagnosticEngine &getDiags() const { return Diagnostics; }
llvm::vfs::FileSystem &getFileSystem() { return *SourceMgr.getFileSystem(); }
ASTContext &getASTContext() { return *Context; }
const ASTContext &getASTContext() const { return *Context; }
bool hasASTContext() const { return Context != nullptr; }
SILOptions &getSILOptions() { return Invocation.getSILOptions(); }
const SILOptions &getSILOptions() const { return Invocation.getSILOptions(); }
Lowering::TypeConverter &getSILTypes();
void createSILModule();
void addDiagnosticConsumer(DiagnosticConsumer *DC) {
Diagnostics.addConsumer(*DC);
}
void removeDiagnosticConsumer(DiagnosticConsumer *DC) {
Diagnostics.removeConsumer(*DC);
}
void createDependencyTracker(bool TrackSystemDeps) {
assert(!Context && "must be called before setup()");
DepTracker = std::make_unique<DependencyTracker>(TrackSystemDeps);
}
DependencyTracker *getDependencyTracker() { return DepTracker.get(); }
const DependencyTracker *getDependencyTracker() const { return DepTracker.get(); }
UnifiedStatsReporter *getStatsReporter() const { return Stats.get(); }
SILModule *getSILModule() {
return TheSILModule.get();
}
std::unique_ptr<SILModule> takeSILModule();
bool hasSILModule() {
return static_cast<bool>(TheSILModule);
}
ModuleDecl *getMainModule() const;
MemoryBufferSerializedModuleLoader *
getMemoryBufferSerializedModuleLoader() const {
return MemoryBufferLoader;
}
ArrayRef<unsigned> getInputBufferIDs() const {
return InputSourceCodeBufferIDs;
}
ArrayRef<LinkLibrary> getLinkLibraries() const {
return Invocation.getLinkLibraries();
}
bool hasSourceImport() const {
return Invocation.getFrontendOptions().EnableSourceImport;
}
/// Gets the set of SourceFiles which are the primary inputs for this
/// CompilerInstance.
ArrayRef<SourceFile *> getPrimarySourceFiles() const {
return PrimarySourceFiles;
}
/// Gets the SourceFile which is the primary input for this CompilerInstance.
/// \returns the primary SourceFile, or nullptr if there is no primary input;
/// if there are _multiple_ primary inputs, fails with an assertion.
///
/// FIXME: This should be removed eventually, once there are no longer any
/// codepaths that rely on a single primary file.
SourceFile *getPrimarySourceFile() const {
if (PrimarySourceFiles.empty()) {
return nullptr;
} else {
assert(PrimarySourceFiles.size() == 1);
return *PrimarySourceFiles.begin();
}
}
/// Returns true if there was an error during setup.
bool setup(const CompilerInvocation &Invocation);
const CompilerInvocation &getInvocation() {
return Invocation;
}
/// If a code completion buffer has been set, returns the corresponding source
/// file.
NullablePtr<SourceFile> getCodeCompletionFile() { return CodeCompletionFile; }
/// Set a new file that we're performing code completion on.
void setCodeCompletionFile(SourceFile *file) {
CodeCompletionFile = file;
}
private:
/// Set up the file system by loading and validating all VFS overlay YAML
/// files. If the process of validating VFS files failed, or the overlay
/// file system could not be initialized, this function returns true. Else it
/// returns false if setup succeeded.
bool setUpVirtualFileSystemOverlays();
void setUpLLVMArguments();
void setUpDiagnosticOptions();
bool setUpModuleLoaders();
bool isInputSwift() {
return Invocation.getInputKind() == InputFileKind::Swift;
}
bool isInSILMode() {
return Invocation.getInputKind() == InputFileKind::SIL;
}
bool setUpInputs();
bool setUpASTContextIfNeeded();
void setupStatsReporter();
Optional<unsigned> setUpCodeCompletionBuffer();
/// Set up all state in the CompilerInstance to process the given input file.
/// Return true on error.
bool setUpForInput(const InputFile &input);
/// Find a buffer for a given input file and ensure it is recorded in
/// SourceMgr, PartialModules, or InputSourceCodeBufferIDs as appropriate.
/// Return the buffer ID if it is not already compiled, or None if so.
/// Set failed on failure.
Optional<unsigned> getRecordedBufferID(const InputFile &input, bool &failed);
/// Given an input file, return a buffer to use for its contents,
/// and a buffer for the corresponding module doc file if one exists.
/// On failure, return a null pointer for the first element of the returned
/// pair.
Optional<ModuleBuffers> getInputBuffersIfPresent(const InputFile &input);
/// Try to open the module doc file corresponding to the input parameter.
/// Return None for error, nullptr if no such file exists, or the buffer if
/// one was found.
Optional<std::unique_ptr<llvm::MemoryBuffer>>
openModuleDoc(const InputFile &input);
/// Try to open the module source info file corresponding to the input parameter.
/// Return None for error, nullptr if no such file exists, or the buffer if
/// one was found.
Optional<std::unique_ptr<llvm::MemoryBuffer>>
openModuleSourceInfo(const InputFile &input);
public:
/// Parses and type-checks all input files.
void performSema();
/// Parses the input file but does no type-checking or module imports.
void performParseOnly(bool EvaluateConditionals = false,
bool CanDelayBodies = true);
/// Parses and performs name binding on all input files.
///
/// This is similar to a parse-only invocation, but module imports will also
/// be processed.
void performParseAndResolveImportsOnly();
/// Performs mandatory, diagnostic, and optimization passes over the SIL.
/// \param silModule The SIL module that was generated during SILGen.
/// \param stats A stats reporter that will report optimization statistics.
/// \returns true if any errors occurred.
bool performSILProcessing(SILModule *silModule);
private:
SourceFile *
createSourceFileForMainModule(SourceFileKind FileKind,
SourceFile::ImplicitModuleImportKind ImportKind,
Optional<unsigned> BufferID);
public:
void freeASTContext();
/// Frees up the SILModule that this instance is holding on to.
void freeSILModule();
private:
/// Load stdlib & return true if should continue, i.e. no error
bool loadStdlib();
ModuleDecl *importUnderlyingModule();
ModuleDecl *importBridgingHeader();
void
getImplicitlyImportedModules(SmallVectorImpl<ModuleDecl *> &importModules);
public: // for static functions in Frontend.cpp
struct ImplicitImports {
SourceFile::ImplicitModuleImportKind kind;
ModuleDecl *objCModuleUnderlyingMixedFramework;
ModuleDecl *headerModule;
SmallVector<ModuleDecl *, 4> modules;
explicit ImplicitImports(CompilerInstance &compiler);
};
static void addAdditionalInitialImportsTo(
SourceFile *SF, const ImplicitImports &implicitImports);
private:
void addMainFileToModule(const ImplicitImports &implicitImports);
void performSemaUpTo(SourceFile::ASTStage_t LimitStage);
void parseAndCheckTypesUpTo(const ImplicitImports &implicitImports,
SourceFile::ASTStage_t LimitStage);
void parseLibraryFile(unsigned BufferID,
const ImplicitImports &implicitImports);
/// Return true if had load error
bool
parsePartialModulesAndLibraryFiles(const ImplicitImports &implicitImports);
void forEachFileToTypeCheck(llvm::function_ref<void(SourceFile &)> fn);
void parseAndTypeCheckMainFileUpTo(SourceFile::ASTStage_t LimitStage);
void finishTypeChecking();
public:
const PrimarySpecificPaths &
getPrimarySpecificPathsForWholeModuleOptimizationMode() const;
const PrimarySpecificPaths &
getPrimarySpecificPathsForPrimary(StringRef filename) const;
const PrimarySpecificPaths &
getPrimarySpecificPathsForAtMostOnePrimary() const;
const PrimarySpecificPaths &
getPrimarySpecificPathsForSourceFile(const SourceFile &SF) const;
/// Write out the unparsed (delayed) source ranges
/// Return true for error
bool emitSwiftRanges(DiagnosticEngine &diags, SourceFile *primaryFile,
StringRef outputPath) const;
/// Return true for error
bool emitCompiledSource(DiagnosticEngine &diags,
const SourceFile *primaryFile,
StringRef outputPath) const;
};
} // namespace swift
#endif