//===--- SerializedModuleLoader.h - Import Swift modules --------*- c++ -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// #ifndef SWIFT_SERIALIZATION_MODULELOADER_H #define SWIFT_SERIALIZATION_MODULELOADER_H #include "swift/AST/Module.h" #include "swift/AST/ModuleLoader.h" #include "llvm/Support/MemoryBuffer.h" #include namespace swift { class ModuleFile; /// Describes whether a loaded module can be used. enum class ModuleStatus { /// The module is valid. Valid, /// The module file format is too old to be used by this version of the /// compiler. FormatTooOld, /// The module file format is too new to be used by this version of the /// compiler. FormatTooNew, /// The module file depends on another module that can't be loaded. MissingDependency, /// The module file is an overlay for a Clang module, which can't be found. MissingShadowedModule, /// The module file is malformed in some way. Malformed, /// The module documentation file is malformed in some way. MalformedDocumentation, /// The module file's name does not match the module it is being loaded into. NameMismatch, /// The module file was built for a different target platform. TargetIncompatible, /// The module file was built for a target newer than the current target. TargetTooNew }; /// \brief Imports serialized Swift modules into an ASTContext. class SerializedModuleLoader : public ModuleLoader { private: ASTContext &Ctx; llvm::StringMap> MemoryBuffers; /// A { module, generation # } pair. using LoadedModulePair = std::pair, unsigned>; std::vector LoadedModuleFiles; explicit SerializedModuleLoader(ASTContext &ctx, DependencyTracker *tracker); public: /// \brief Create a new importer that can load serialized Swift modules /// into the given ASTContext. static std::unique_ptr create(ASTContext &ctx, DependencyTracker *tracker = nullptr) { return std::unique_ptr{ new SerializedModuleLoader(ctx, tracker) }; } ~SerializedModuleLoader(); SerializedModuleLoader(const SerializedModuleLoader &) = delete; SerializedModuleLoader(SerializedModuleLoader &&) = delete; SerializedModuleLoader &operator=(const SerializedModuleLoader &) = delete; SerializedModuleLoader &operator=(SerializedModuleLoader &&) = delete; /// \brief Import a module with the given module path. /// /// \param importLoc The location of the 'import' keyword. /// /// \param path A sequence of (identifier, location) pairs that denote /// the dotted module name to load, e.g., AppKit.NSWindow. /// /// \returns the module referenced, if it could be loaded. Otherwise, /// emits a diagnostic and returns a FailedImportModule object. virtual Module * loadModule(SourceLoc importLoc, ArrayRef> path) override; /// Attempt to load a serialized AST into the given module. /// /// If the AST cannot be loaded and \p diagLoc is present, a diagnostic is /// printed. (Note that \p diagLoc is allowed to be invalid.) FileUnit *loadAST(Module &M, Optional diagLoc, std::unique_ptr moduleInputBuffer, std::unique_ptr moduleDocInputBuffer, bool isFramework = false); /// \brief Register a memory buffer that contains the serialized /// module for the given access path. This API is intended to be /// used by LLDB to add swiftmodules discovered in the __apple_ast /// section of a Mach-O file to the search path. /// FIXME: make this an actual access *path* once submodules are designed. void registerMemoryBuffer(StringRef AccessPath, std::unique_ptr input) { MemoryBuffers[AccessPath] = std::move(input); } virtual void loadExtensions(NominalTypeDecl *nominal, unsigned previousGeneration) override; virtual void loadObjCMethods( ClassDecl *classDecl, ObjCSelector selector, bool isInstanceMethod, unsigned previousGeneration, llvm::TinyPtrVector &methods); /// Returns true if the data looks like it contains a serialized AST. static bool isSerializedAST(StringRef data); /// \see validateSerializedAST() struct ValidationInfo { StringRef name = {}; StringRef targetTriple = {}; size_t bytes = 0; ModuleStatus status = ModuleStatus::Malformed; }; /// Returns info about the serialized AST in the given data. /// /// If the returned status is anything but ModuleStatus::Valid, the /// serialized data cannot be loaded by this version of the compiler. If the /// returned size is non-zero, it's possible to skip over this module's data, /// in case there is more data in the buffer. The returned name, which may /// be empty, directly points into the given data buffer. /// /// Note that this does not actually try to load the module or validate any /// of its dependencies; it only checks that it /can/ be loaded. static ValidationInfo validateSerializedAST(StringRef data); virtual void verifyAllModules() override; }; /// A file-unit loaded from a serialized AST file. class SerializedASTFile final : public LoadedFile { friend class SerializedModuleLoader; friend class SerializedSILLoader; ModuleFile &File; ~SerializedASTFile() = default; SerializedASTFile(Module &M, ModuleFile &file) : LoadedFile(FileUnitKind::SerializedAST, M), File(file) {} public: ModuleFile &getFile() const { return File; } virtual bool isSystemModule() const override; virtual void lookupValue(Module::AccessPathTy accessPath, DeclName name, NLKind lookupKind, SmallVectorImpl &results) const override; virtual TypeDecl *lookupLocalType(StringRef MangledName) const override; virtual OperatorDecl *lookupOperator(Identifier name, DeclKind fixity) const override; virtual void lookupVisibleDecls(Module::AccessPathTy accessPath, VisibleDeclConsumer &consumer, NLKind lookupKind) const override; virtual void lookupClassMembers(Module::AccessPathTy accessPath, VisibleDeclConsumer &consumer) const override; virtual void lookupClassMember(Module::AccessPathTy accessPath, DeclName name, SmallVectorImpl &decls) const override; Optional getCommentForDecl(const Decl *D) const override; virtual void getTopLevelDecls(SmallVectorImpl &results) const override; virtual void getLocalTypeDecls(SmallVectorImpl &results) const override; virtual void getDisplayDecls(SmallVectorImpl &results) const override; virtual void getImportedModules(SmallVectorImpl &imports, Module::ImportFilter filter) const override; virtual void collectLinkLibraries(Module::LinkLibraryCallback callback) const override; Identifier getDiscriminatorForPrivateValue(const ValueDecl *D) const override; virtual StringRef getFilename() const override; ClassDecl *getMainClass() const override; bool hasEntryPoint() const override; virtual const clang::Module *getUnderlyingClangModule() override; static bool classof(const FileUnit *file) { return file->getKind() == FileUnitKind::SerializedAST; } static bool classof(const DeclContext *DC) { return isa(DC) && classof(cast(DC)); } }; } // end namespace swift #endif