diff --git a/include/swift/AST/ASTTypeIDZone.def b/include/swift/AST/ASTTypeIDZone.def index 0a49cbc03c8eb..103b382e9ba50 100644 --- a/include/swift/AST/ASTTypeIDZone.def +++ b/include/swift/AST/ASTTypeIDZone.def @@ -19,6 +19,7 @@ SWIFT_TYPEID(AncestryFlags) SWIFT_TYPEID(CtorInitializerKind) SWIFT_TYPEID(FunctionBuilderBodyPreCheck) SWIFT_TYPEID(GenericSignature) +SWIFT_TYPEID(ImplicitImport) SWIFT_TYPEID(ImplicitMemberAction) SWIFT_TYPEID(ParamSpecifier) SWIFT_TYPEID(PropertyWrapperBackingPropertyInfo) diff --git a/include/swift/AST/ASTTypeIDs.h b/include/swift/AST/ASTTypeIDs.h index 5adba9595746c..c4bebdfade92b 100644 --- a/include/swift/AST/ASTTypeIDs.h +++ b/include/swift/AST/ASTTypeIDs.h @@ -36,6 +36,7 @@ class GenericTypeParamType; class InfixOperatorDecl; class IterableDeclContext; class ModuleDecl; +struct ImplicitImport; class NamedPattern; class NominalTypeDecl; class OperatorDecl; diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h index 37d1980786131..ea92c738d39a0 100644 --- a/include/swift/AST/Decl.h +++ b/include/swift/AST/Decl.h @@ -3032,6 +3032,10 @@ class TypeAliasDecl : public GenericTypeDecl { Type getUnderlyingType() const; void setUnderlyingType(Type type); + /// Returns the interface type of the underlying type if computed, null + /// otherwise. Should only be used for dumping. + Type getCachedUnderlyingType() const { return UnderlyingTy.getType(); } + /// For generic typealiases, return the unbound generic type. UnboundGenericType *getUnboundGenericType() const; diff --git a/include/swift/AST/DiagnosticsCommon.def b/include/swift/AST/DiagnosticsCommon.def index a5bebe4123280..954363a3fdef6 100644 --- a/include/swift/AST/DiagnosticsCommon.def +++ b/include/swift/AST/DiagnosticsCommon.def @@ -90,6 +90,10 @@ ERROR(attr_only_on_parameters, none, ERROR(function_type_no_parens,none, "single argument function types require parentheses", ()) +// Used by both the Frontend and Sema. +ERROR(error_underlying_module_not_found,none, + "underlying Objective-C module %0 not found", (Identifier)) + // Used by -verify-generic-signatures ERROR(generic_signature_not_minimal,none, "generic requirement '%0' is redundant in %1", (StringRef, StringRef)) diff --git a/include/swift/AST/DiagnosticsFrontend.def b/include/swift/AST/DiagnosticsFrontend.def index 4ed1d7a62d92e..7294b0a274344 100644 --- a/include/swift/AST/DiagnosticsFrontend.def +++ b/include/swift/AST/DiagnosticsFrontend.def @@ -138,8 +138,6 @@ ERROR(error_stdlib_module_name,none, ERROR(error_stdlib_not_found,Fatal, "unable to load standard library for target '%0'", (StringRef)) -ERROR(error_underlying_module_not_found,none, - "underlying Objective-C module %0 not found", (Identifier)) ERROR(error_unable_to_load_supplementary_output_file_map, none, "unable to load supplementary output file map '%0': %1", diff --git a/include/swift/AST/Module.h b/include/swift/AST/Module.h index ea7ee3c24b85d..d127620e12fb8 100644 --- a/include/swift/AST/Module.h +++ b/include/swift/AST/Module.h @@ -59,6 +59,7 @@ namespace swift { class FuncDecl; class InfixOperatorDecl; class LinkLibrary; + struct ImplicitImport; class ModuleLoader; class NominalTypeDecl; class EnumElementDecl; @@ -158,6 +159,42 @@ enum class ResilienceStrategy : unsigned { Resilient }; +/// The kind of stdlib that should be imported. +enum class ImplicitStdlibKind { + /// No standard library should be implicitly imported. + None, + + /// The Builtin module should be implicitly imported. + Builtin, + + /// The regular Swift standard library should be implicitly imported. + Stdlib +}; + +struct ImplicitImportInfo { + /// The implicit stdlib to import. + ImplicitStdlibKind StdlibKind; + + /// Whether we should attempt to import an underlying Clang half of this + /// module. + bool ShouldImportUnderlyingModule; + + /// The bridging header path for this module, empty if there is none. + StringRef BridgingHeaderPath; + + /// The names of additional modules to be implicitly imported. + SmallVector ModuleNames; + + /// An additional list of already-loaded modules which should be implicitly + /// imported. + SmallVector, 4> + AdditionalModules; + + ImplicitImportInfo() + : StdlibKind(ImplicitStdlibKind::None), + ShouldImportUnderlyingModule(false) {} +}; + class OverlayFile; /// The minimum unit of compilation. @@ -245,6 +282,10 @@ class ModuleDecl : public DeclContext, public TypeDecl { llvm::SmallDenseMap> declaredCrossImports; + /// A description of what should be implicitly imported by each file of this + /// module. + const ImplicitImportInfo ImportInfo; + std::unique_ptr Cache; SourceLookupCache &getSourceLookupCache() const; @@ -274,15 +315,29 @@ class ModuleDecl : public DeclContext, public TypeDecl { /// \see EntryPointInfoTy EntryPointInfoTy EntryPointInfo; - ModuleDecl(Identifier name, ASTContext &ctx); + ModuleDecl(Identifier name, ASTContext &ctx, ImplicitImportInfo importInfo); public: - static ModuleDecl *create(Identifier name, ASTContext &ctx) { - return new (ctx) ModuleDecl(name, ctx); + /// Creates a new module with a given \p name. + /// + /// \param importInfo Information about which modules should be implicitly + /// imported by each file of this module. + static ModuleDecl * + create(Identifier name, ASTContext &ctx, + ImplicitImportInfo importInfo = ImplicitImportInfo()) { + return new (ctx) ModuleDecl(name, ctx, importInfo); } using Decl::getASTContext; + /// Retrieves information about which modules are implicitly imported by + /// each file of this module. + const ImplicitImportInfo &getImplicitImportInfo() const { return ImportInfo; } + + /// Retrieve a list of modules that each file of this module implicitly + /// imports. + ArrayRef getImplicitImports() const; + ArrayRef getFiles() { return Files; } diff --git a/include/swift/AST/SourceFile.h b/include/swift/AST/SourceFile.h index b3fcb9ac66973..3ca6abb78dae0 100644 --- a/include/swift/AST/SourceFile.h +++ b/include/swift/AST/SourceFile.h @@ -33,13 +33,6 @@ class SourceFile final : public FileUnit { class Impl; struct SourceFileSyntaxInfo; - /// The implicit module import that the SourceFile should get. - enum class ImplicitModuleImportKind { - None, - Builtin, - Stdlib - }; - /// Possible attributes for imports in source files. enum class ImportFlags { /// The imported module is exposed to anyone who imports the parent module. @@ -128,8 +121,8 @@ class SourceFile final : public FileUnit { /// This is the list of modules that are imported by this module. /// - /// This is filled in by the import resolution phase. - ArrayRef Imports; + /// This is \c None until it is filled in by the import resolution phase. + Optional> Imports; /// A unique identifier representing this file; used to mark private decls /// within the file to keep them from conflicting with other files in the @@ -335,12 +328,14 @@ class SourceFile final : public FileUnit { llvm::StringMap getInfoForUsedFilePaths() const; SourceFile(ModuleDecl &M, SourceFileKind K, Optional bufferID, - ImplicitModuleImportKind ModImpKind, bool KeepParsedTokens = false, - bool KeepSyntaxTree = false, ParsingOptions parsingOpts = {}); + bool KeepParsedTokens = false, bool KeepSyntaxTree = false, + ParsingOptions parsingOpts = {}); ~SourceFile(); - void addImports(ArrayRef IM); + /// Set the imports for this source file. This gets called by import + /// resolution. + void setImports(ArrayRef imports); enum ImportQueryKind { /// Return the results for testable or private imports. diff --git a/include/swift/AST/TypeCheckRequests.h b/include/swift/AST/TypeCheckRequests.h index ee53927a86ebd..202a12b212847 100644 --- a/include/swift/AST/TypeCheckRequests.h +++ b/include/swift/AST/TypeCheckRequests.h @@ -23,6 +23,7 @@ #include "swift/AST/Evaluator.h" #include "swift/AST/Pattern.h" #include "swift/AST/SimpleRequest.h" +#include "swift/AST/SourceFile.h" #include "swift/AST/TypeResolutionStage.h" #include "swift/Basic/AnyValue.h" #include "swift/Basic/Statistic.h" @@ -2344,6 +2345,45 @@ class SimpleDidSetRequest } }; +/// A module which has been implicitly imported. +struct ImplicitImport { + using ImportOptions = SourceFile::ImportOptions; + + ModuleDecl *Module; + ImportOptions Options; + + ImplicitImport(ModuleDecl *module, ImportOptions opts = {}) + : Module(module), Options(opts) {} + + friend bool operator==(const ImplicitImport &lhs, + const ImplicitImport &rhs) { + return lhs.Module == rhs.Module && + lhs.Options.toRaw() == rhs.Options.toRaw(); + } +}; + +void simple_display(llvm::raw_ostream &out, const ImplicitImport &import); + +/// Computes the loaded modules that should be implicitly imported by each file +/// of a given module. +class ModuleImplicitImportsRequest + : public SimpleRequest(ModuleDecl *), + RequestFlags::Cached> { +public: + using SimpleRequest::SimpleRequest; + +private: + friend SimpleRequest; + + ArrayRef + evaluate(Evaluator &evaluator, ModuleDecl *module) const; + +public: + // Cached. + bool isCached() const { return true; } +}; + // Allow AnyValue to compare two Type values, even though Type doesn't // support ==. template<> diff --git a/include/swift/AST/TypeCheckerTypeIDZone.def b/include/swift/AST/TypeCheckerTypeIDZone.def index ea2ffdf7144a3..b86811ae0981a 100644 --- a/include/swift/AST/TypeCheckerTypeIDZone.def +++ b/include/swift/AST/TypeCheckerTypeIDZone.def @@ -128,6 +128,8 @@ SWIFT_REQUEST(TypeChecker, ValidatePrecedenceGroupRequest, Cached, NoLocationInfo) SWIFT_REQUEST(TypeChecker, MangleLocalTypeDeclRequest, std::string(const TypeDecl *), Cached, NoLocationInfo) +SWIFT_REQUEST(TypeChecker, ModuleImplicitImportsRequest, + ArrayRef(ModuleDecl *), Cached, NoLocationInfo) SWIFT_REQUEST(TypeChecker, NamingPatternRequest, NamedPattern *(VarDecl *), SeparatelyCached, NoLocationInfo) SWIFT_REQUEST(TypeChecker, OpaqueReadOwnershipRequest, diff --git a/include/swift/Frontend/Frontend.h b/include/swift/Frontend/Frontend.h index 7718407233f5d..a1b2197fd13a9 100644 --- a/include/swift/Frontend/Frontend.h +++ b/include/swift/Frontend/Frontend.h @@ -335,14 +335,15 @@ class CompilerInvocation { /// in generating a cached PCH file for the bridging header. std::string getPCHHash() const; - SourceFile::ImplicitModuleImportKind getImplicitModuleImportKind() const { + /// Retrieve the stdlib kind to implicitly import. + ImplicitStdlibKind getImplicitStdlibKind() const { if (getInputKind() == InputFileKind::SIL) { - return SourceFile::ImplicitModuleImportKind::None; + return ImplicitStdlibKind::None; } if (getParseStdlib()) { - return SourceFile::ImplicitModuleImportKind::Builtin; + return ImplicitStdlibKind::Builtin; } - return SourceFile::ImplicitModuleImportKind::Stdlib; + return ImplicitStdlibKind::Stdlib; } /// Performs input setup common to these tools: @@ -654,7 +655,6 @@ class CompilerInstance { private: SourceFile * createSourceFileForMainModule(SourceFileKind FileKind, - SourceFile::ImplicitModuleImportKind ImportKind, Optional BufferID, SourceFile::ParsingOptions options = {}); @@ -667,38 +667,17 @@ class CompilerInstance { private: /// Load stdlib & return true if should continue, i.e. no error bool loadStdlib(); - ModuleDecl *importUnderlyingModule(); - ModuleDecl *importBridgingHeader(); - void - getImplicitlyImportedModules(SmallVectorImpl &importModules); - -public: // for static functions in Frontend.cpp - struct ImplicitImports { - SourceFile::ImplicitModuleImportKind kind; - ModuleDecl *objCModuleUnderlyingMixedFramework; - ModuleDecl *headerModule; - SmallVector modules; - - explicit ImplicitImports(CompilerInstance &compiler); - }; - - static void addAdditionalInitialImportsTo( - SourceFile *SF, const ImplicitImports &implicitImports); - -private: - void addMainFileToModule(const ImplicitImports &implicitImports); + /// Retrieve a description of which modules should be implicitly imported. + ImplicitImportInfo getImplicitImportInfo() const; void performSemaUpTo(SourceFile::ASTStage_t LimitStage); - void parseAndCheckTypesUpTo(const ImplicitImports &implicitImports, - SourceFile::ASTStage_t LimitStage); + void parseAndCheckTypesUpTo(SourceFile::ASTStage_t LimitStage); - void parseLibraryFile(unsigned BufferID, - const ImplicitImports &implicitImports); + void parseLibraryFile(unsigned BufferID); /// Return true if had load error - bool - parsePartialModulesAndLibraryFiles(const ImplicitImports &implicitImports); + bool parsePartialModulesAndLibraryFiles(); void forEachFileToTypeCheck(llvm::function_ref fn); diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h index 81f72772239a0..fc83b750579d6 100644 --- a/include/swift/Frontend/FrontendOptions.h +++ b/include/swift/Frontend/FrontendOptions.h @@ -33,6 +33,9 @@ namespace swift { class FrontendOptions { friend class ArgsToFrontendOptionsConverter; + /// A list of arbitrary modules to import and make implicitly visible. + std::vector ImplicitImportModuleNames; + public: FrontendInputsAndOutputs InputsAndOutputs; @@ -44,9 +47,6 @@ class FrontendOptions { bool isOutputFileDirectory() const; - /// A list of arbitrary modules to import and make implicitly visible. - std::vector ImplicitImportModuleNames; - /// An Objective-C header to import and make implicitly visible. std::string ImplicitObjCHeaderPath; @@ -322,6 +322,12 @@ class FrontendOptions { const PrimarySpecificPaths & getPrimarySpecificPathsForPrimary(StringRef) const; + /// Retrieves the list of arbitrary modules to import and make implicitly + /// visible. + ArrayRef getImplicitImportModuleNames() const { + return ImplicitImportModuleNames; + } + private: static bool canActionEmitDependencies(ActionType); static bool canActionEmitReferenceDependencies(ActionType); diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index dbd73c8776156..a2d864c93dae7 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -631,7 +631,7 @@ namespace { void visitTypeAliasDecl(TypeAliasDecl *TAD) { printCommon(TAD, "typealias"); PrintWithColorRAII(OS, TypeColor) << " type='"; - if (auto underlying = TAD->getUnderlyingType()) { + if (auto underlying = TAD->getCachedUnderlyingType()) { PrintWithColorRAII(OS, TypeColor) << underlying.getString(); } else { diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp index 6399871c0f737..e4c80e2b86e47 100644 --- a/lib/AST/Module.cpp +++ b/lib/AST/Module.cpp @@ -464,9 +464,11 @@ void SourceLookupCache::invalidate() { // Module Implementation //===----------------------------------------------------------------------===// -ModuleDecl::ModuleDecl(Identifier name, ASTContext &ctx) - : DeclContext(DeclContextKind::Module, nullptr), - TypeDecl(DeclKind::Module, &ctx, name, SourceLoc(), { }) { +ModuleDecl::ModuleDecl(Identifier name, ASTContext &ctx, + ImplicitImportInfo importInfo) + : DeclContext(DeclContextKind::Module, nullptr), + TypeDecl(DeclKind::Module, &ctx, name, SourceLoc(), {}), + ImportInfo(importInfo) { ctx.addDestructorCleanup(*this); setImplicit(); @@ -475,6 +477,13 @@ ModuleDecl::ModuleDecl(Identifier name, ASTContext &ctx) setAccess(AccessLevel::Public); } +ArrayRef ModuleDecl::getImplicitImports() const { + auto &evaluator = getASTContext().evaluator; + auto *mutableThis = const_cast(this); + return evaluateOrDefault(evaluator, ModuleImplicitImportsRequest{mutableThis}, + {}); +} + bool ModuleDecl::isClangModule() const { return findUnderlyingClangModule() != nullptr; } @@ -1094,7 +1103,7 @@ class SourceFile::Impl { /// Only intended for use by lookupOperatorDeclForName. static ArrayRef getImportsForSourceFile(const SourceFile &SF) { - return SF.Imports; + return *SF.Imports; } }; @@ -1399,7 +1408,10 @@ SourceFile::getImportedModules(SmallVectorImpl &modu // We currently handle this for a direct import from the overlay, but not when // it happens through other imports. assert(filter && "no imports requested?"); - for (auto desc : Imports) { + if (!Imports) + return; + + for (auto desc : *Imports) { ModuleDecl::ImportFilter requiredFilter; if (desc.importOptions.contains(ImportFlags::Exported)) requiredFilter |= ModuleDecl::ImportFilterKind::Public; @@ -2027,23 +2039,14 @@ void SourceFile::print(ASTPrinter &Printer, const PrintOptions &PO) { } } -void SourceFile::addImports(ArrayRef IM) { - if (IM.empty()) - return; - ASTContext &ctx = getASTContext(); - auto newBuf = - ctx.AllocateUninitialized(Imports.size() + IM.size()); - - auto iter = newBuf.begin(); - iter = std::uninitialized_copy(Imports.begin(), Imports.end(), iter); - iter = std::uninitialized_copy(IM.begin(), IM.end(), iter); - assert(iter == newBuf.end()); - - Imports = newBuf; +void SourceFile::setImports(ArrayRef imports) { + assert(!Imports && "Already computed imports"); + Imports = getASTContext().AllocateCopy(imports); // Update the HasImplementationOnlyImports flag. + // TODO: Requestify this. if (!HasImplementationOnlyImports) { - for (auto &desc : IM) { + for (auto &desc : imports) { if (desc.importOptions.contains(ImportFlags::ImplementationOnly)) HasImplementationOnlyImports = true; } @@ -2061,7 +2064,7 @@ bool SourceFile::hasTestableOrPrivateImport( // filename does not need to match (and we don't serialize it for such // decls). return std::any_of( - Imports.begin(), Imports.end(), + Imports->begin(), Imports->end(), [module, queryKind](ImportedModuleDesc desc) -> bool { if (queryKind == ImportQueryKind::TestableAndPrivate) return desc.module.second == module && @@ -2103,7 +2106,7 @@ bool SourceFile::hasTestableOrPrivateImport( if (filename.empty()) return false; - return std::any_of(Imports.begin(), Imports.end(), + return std::any_of(Imports->begin(), Imports->end(), [module, filename](ImportedModuleDesc desc) -> bool { return desc.module.second == module && desc.importOptions.contains( @@ -2121,7 +2124,7 @@ bool SourceFile::isImportedImplementationOnly(const ModuleDecl *module) const { auto &imports = getASTContext().getImportCache(); // Look at the imports of this source file. - for (auto &desc : Imports) { + for (auto &desc : *Imports) { // Ignore implementation-only imports. if (desc.importOptions.contains(ImportFlags::ImplementationOnly)) continue; @@ -2138,7 +2141,7 @@ bool SourceFile::isImportedImplementationOnly(const ModuleDecl *module) const { void SourceFile::lookupImportedSPIGroups(const ModuleDecl *importedModule, SmallVectorImpl &spiGroups) const { - for (auto &import : Imports) { + for (auto &import : *Imports) { if (import.importOptions.contains(ImportFlags::SPIAccessControl) && importedModule == std::get(import.module)) { auto importedSpis = import.spiGroups; @@ -2245,36 +2248,6 @@ SourceFile::getCachedVisibleDecls() const { return getCache().AllVisibleValues; } -static void performAutoImport( - SourceFile &SF, - SourceFile::ImplicitModuleImportKind implicitModuleImportKind) { - if (SF.Kind == SourceFileKind::SIL) - assert(implicitModuleImportKind == - SourceFile::ImplicitModuleImportKind::None); - - ASTContext &Ctx = SF.getASTContext(); - ModuleDecl *M = nullptr; - - switch (implicitModuleImportKind) { - case SourceFile::ImplicitModuleImportKind::None: - return; - case SourceFile::ImplicitModuleImportKind::Builtin: - M = Ctx.TheBuiltinModule; - break; - case SourceFile::ImplicitModuleImportKind::Stdlib: - M = Ctx.getStdlibModule(true); - break; - } - - assert(M && "unable to auto-import module"); - - // FIXME: These will be the same for most source files, but we copy them - // over and over again. - auto Imports = SourceFile::ImportedModuleDesc( - ModuleDecl::ImportedModule({}, M), SourceFile::ImportOptions()); - SF.addImports(Imports); -} - llvm::StringMap SourceFile::getInfoForUsedFilePaths() const { llvm::StringMap result; @@ -2415,14 +2388,12 @@ ModuleDecl::computeMagicFileStringMap(bool shouldDiagnose) const { SourceFile::SourceFile(ModuleDecl &M, SourceFileKind K, Optional bufferID, - ImplicitModuleImportKind ModImpKind, bool KeepParsedTokens, bool BuildSyntaxTree, ParsingOptions parsingOpts) : FileUnit(FileUnitKind::Source, M), BufferID(bufferID ? *bufferID : -1), ParsingOpts(parsingOpts), Kind(K), SyntaxInfo(new SourceFileSyntaxInfo(BuildSyntaxTree)) { M.getASTContext().addDestructorCleanup(*this); - performAutoImport(*this, ModImpKind); if (isScriptMode()) { bool problem = M.registerEntryPointFile(this, SourceLoc(), None); diff --git a/lib/AST/TypeCheckRequests.cpp b/lib/AST/TypeCheckRequests.cpp index 2f4c907fad789..426f21baf5625 100644 --- a/lib/AST/TypeCheckRequests.cpp +++ b/lib/AST/TypeCheckRequests.cpp @@ -1499,3 +1499,13 @@ TypeCheckFunctionBodyUntilRequest::readDependencySource(Evaluator &e) const { evaluator::DependencyScope::Private }; } + +//----------------------------------------------------------------------------// +// ModuleImplicitImportsRequest computation. +//----------------------------------------------------------------------------// + +void swift::simple_display(llvm::raw_ostream &out, + const ImplicitImport &import) { + out << "implicit import of "; + simple_display(out, import.Module); +} diff --git a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp index ee15319517670..e45159868a946 100644 --- a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp +++ b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp @@ -564,7 +564,13 @@ void ArgsToFrontendOptionsConverter::computeImportObjCHeaderOptions() { void ArgsToFrontendOptionsConverter::computeImplicitImportModuleNames() { using namespace options; for (const Arg *A : Args.filtered(OPT_import_module)) { - Opts.ImplicitImportModuleNames.push_back(A->getValue()); + auto *moduleStr = A->getValue(); + if (!Lexer::isIdentifier(moduleStr)) { + Diags.diagnose(SourceLoc(), diag::error_bad_module_name, moduleStr, + /*suggestModuleNameFlag*/ false); + continue; + } + Opts.ImplicitImportModuleNames.push_back(moduleStr); } } void ArgsToFrontendOptionsConverter::computeLLVMArgs() { diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index b162e549d05fe..37eaf7cdb4330 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -692,57 +692,13 @@ std::unique_ptr CompilerInstance::takeSILModule() { return std::move(TheSILModule); } -ModuleDecl *CompilerInstance::getMainModule() const { - if (!MainModule) { - Identifier ID = Context->getIdentifier(Invocation.getModuleName()); - MainModule = ModuleDecl::create(ID, *Context); - if (Invocation.getFrontendOptions().EnableTesting) - MainModule->setTestingEnabled(); - if (Invocation.getFrontendOptions().EnablePrivateImports) - MainModule->setPrivateImportsEnabled(); - if (Invocation.getFrontendOptions().EnableImplicitDynamic) - MainModule->setImplicitDynamicEnabled(); - - if (Invocation.getFrontendOptions().EnableLibraryEvolution) - MainModule->setResilienceStrategy(ResilienceStrategy::Resilient); - } - return MainModule; -} - -void CompilerInstance::addAdditionalInitialImportsTo( - SourceFile *SF, const CompilerInstance::ImplicitImports &implicitImports) { - SmallVector additionalImports; - - if (implicitImports.objCModuleUnderlyingMixedFramework) - additionalImports.push_back(SourceFile::ImportedModuleDesc( - ModuleDecl::ImportedModule( - /*accessPath=*/{}, - implicitImports.objCModuleUnderlyingMixedFramework), - SourceFile::ImportFlags::Exported)); - if (implicitImports.headerModule) - additionalImports.push_back(SourceFile::ImportedModuleDesc( - ModuleDecl::ImportedModule(/*accessPath=*/{}, - implicitImports.headerModule), - SourceFile::ImportFlags::Exported)); - if (!implicitImports.modules.empty()) { - for (auto &importModule : implicitImports.modules) { - additionalImports.push_back(SourceFile::ImportedModuleDesc( - ModuleDecl::ImportedModule(/*accessPath=*/{}, importModule), - SourceFile::ImportOptions())); - } - } - - SF->addImports(additionalImports); -} - /// 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. -static bool -shouldImplicityImportSwiftOnoneSupportModule(CompilerInvocation &Invocation) { - if (Invocation.getImplicitModuleImportKind() != - SourceFile::ImplicitModuleImportKind::Stdlib) +static bool shouldImplicityImportSwiftOnoneSupportModule( + const CompilerInvocation &Invocation) { + if (Invocation.getImplicitStdlibKind() != ImplicitStdlibKind::Stdlib) return false; if (Invocation.getSILOptions().shouldOptimize()) return false; @@ -764,6 +720,40 @@ shouldImplicityImportSwiftOnoneSupportModule(CompilerInvocation &Invocation) { || FrontendOptions::doesActionGenerateSIL(options.RequestedAction); } +ImplicitImportInfo CompilerInstance::getImplicitImportInfo() const { + auto &frontendOpts = Invocation.getFrontendOptions(); + + ImplicitImportInfo imports; + imports.StdlibKind = Invocation.getImplicitStdlibKind(); + + for (auto &moduleStr : frontendOpts.getImplicitImportModuleNames()) + imports.ModuleNames.push_back(Context->getIdentifier(moduleStr)); + + if (shouldImplicityImportSwiftOnoneSupportModule(Invocation)) + imports.ModuleNames.push_back(Context->getIdentifier(SWIFT_ONONE_SUPPORT)); + + imports.ShouldImportUnderlyingModule = frontendOpts.ImportUnderlyingModule; + imports.BridgingHeaderPath = frontendOpts.ImplicitObjCHeaderPath; + return imports; +} + +ModuleDecl *CompilerInstance::getMainModule() const { + if (!MainModule) { + Identifier ID = Context->getIdentifier(Invocation.getModuleName()); + MainModule = ModuleDecl::create(ID, *Context, getImplicitImportInfo()); + if (Invocation.getFrontendOptions().EnableTesting) + MainModule->setTestingEnabled(); + if (Invocation.getFrontendOptions().EnablePrivateImports) + MainModule->setPrivateImportsEnabled(); + if (Invocation.getFrontendOptions().EnableImplicitDynamic) + MainModule->setImplicitDynamicEnabled(); + + if (Invocation.getFrontendOptions().EnableLibraryEvolution) + MainModule->setResilienceStrategy(ResilienceStrategy::Resilient); + } + return MainModule; +} + void CompilerInstance::performParseAndResolveImportsOnly() { performSemaUpTo(SourceFile::ImportsResolved); } @@ -787,49 +777,33 @@ void CompilerInstance::performSemaUpTo(SourceFile::ASTStage_t LimitStage) { createSILModule(); } - if (Invocation.getImplicitModuleImportKind() == - SourceFile::ImplicitModuleImportKind::Stdlib) { + if (Invocation.getImplicitStdlibKind() == ImplicitStdlibKind::Stdlib) { if (!loadStdlib()) return; } - if (shouldImplicityImportSwiftOnoneSupportModule(Invocation)) { - Invocation.getFrontendOptions().ImplicitImportModuleNames.push_back( - SWIFT_ONONE_SUPPORT.str()); - } - const ImplicitImports implicitImports(*this); + // Force loading implicit imports. This is currently needed to allow + // deserialization to resolve cross references into bridging headers. + // FIXME: Once deserialization loads all the modules it needs for cross + // references, this can be removed. + (void)MainModule->getImplicitImports(); if (Invocation.getInputKind() == InputFileKind::SwiftREPL) { // Create the initial empty REPL file. This only exists to feed in the // implicit imports such as the standard library. - auto *replFile = createSourceFileForMainModule( - SourceFileKind::REPL, implicitImports.kind, /*BufferID*/ None); - addAdditionalInitialImportsTo(replFile, implicitImports); - - // Given this file is empty, we can go ahead and just mark it as having been - // type checked. - replFile->ASTStage = SourceFile::TypeChecked; + auto *replFile = + createSourceFileForMainModule(SourceFileKind::REPL, /*BufferID*/ None); + performImportResolution(*replFile); return; } // Make sure the main file is the first file in the module, so do this now. - if (MainBufferID != NO_SUCH_BUFFER) - addMainFileToModule(implicitImports); - - parseAndCheckTypesUpTo(implicitImports, LimitStage); -} - -CompilerInstance::ImplicitImports::ImplicitImports(CompilerInstance &compiler) { - kind = compiler.Invocation.getImplicitModuleImportKind(); - - objCModuleUnderlyingMixedFramework = - compiler.Invocation.getFrontendOptions().ImportUnderlyingModule - ? compiler.importUnderlyingModule() - : nullptr; - - compiler.getImplicitlyImportedModules(modules); + if (MainBufferID != NO_SUCH_BUFFER) { + (void)createSourceFileForMainModule(Invocation.getSourceFileKind(), + MainBufferID); + } - headerModule = compiler.importBridgingHeader(); + parseAndCheckTypesUpTo(LimitStage); } bool CompilerInstance::loadStdlib() { @@ -851,72 +825,11 @@ bool CompilerInstance::loadStdlib() { return true; } -ModuleDecl *CompilerInstance::importUnderlyingModule() { - FrontendStatsTracer tracer(getStatsReporter(), "import-underlying-module"); - ModuleDecl *objCModuleUnderlyingMixedFramework = - static_cast(Context->getClangModuleLoader()) - ->loadModule(SourceLoc(), - { Located(MainModule->getName(), SourceLoc()) }); - if (objCModuleUnderlyingMixedFramework) - return objCModuleUnderlyingMixedFramework; - Diagnostics.diagnose(SourceLoc(), diag::error_underlying_module_not_found, - MainModule->getName()); - return nullptr; -} - -ModuleDecl *CompilerInstance::importBridgingHeader() { - FrontendStatsTracer tracer(getStatsReporter(), "import-bridging-header"); - const StringRef implicitHeaderPath = - Invocation.getFrontendOptions().ImplicitObjCHeaderPath; - auto clangImporter = - static_cast(Context->getClangModuleLoader()); - if (implicitHeaderPath.empty() || - clangImporter->importBridgingHeader(implicitHeaderPath, MainModule)) - return nullptr; - ModuleDecl *importedHeaderModule = clangImporter->getImportedHeaderModule(); - assert(importedHeaderModule); - return importedHeaderModule; -} - -void CompilerInstance::getImplicitlyImportedModules( - SmallVectorImpl &importModules) { - FrontendStatsTracer tracer(getStatsReporter(), "get-implicitly-imported-modules"); - for (auto &ImplicitImportModuleName : - Invocation.getFrontendOptions().ImplicitImportModuleNames) { - if (Lexer::isIdentifier(ImplicitImportModuleName)) { - auto moduleID = Context->getIdentifier(ImplicitImportModuleName); - ModuleDecl *importModule = - Context->getModule({ Located(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); - } - } -} - -void CompilerInstance::addMainFileToModule( - const ImplicitImports &implicitImports) { - auto *MainFile = createSourceFileForMainModule( - Invocation.getSourceFileKind(), implicitImports.kind, MainBufferID); - addAdditionalInitialImportsTo(MainFile, implicitImports); -} - void CompilerInstance::parseAndCheckTypesUpTo( - const ImplicitImports &implicitImports, SourceFile::ASTStage_t limitStage) { + SourceFile::ASTStage_t limitStage) { FrontendStatsTracer tracer(getStatsReporter(), "parse-and-check-types"); - bool hadLoadError = parsePartialModulesAndLibraryFiles(implicitImports); + bool hadLoadError = parsePartialModulesAndLibraryFiles(); 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 @@ -972,20 +885,17 @@ void CompilerInstance::parseAndCheckTypesUpTo( finishTypeChecking(); } -void CompilerInstance::parseLibraryFile( - unsigned BufferID, const ImplicitImports &implicitImports) { +void CompilerInstance::parseLibraryFile(unsigned BufferID) { FrontendStatsTracer tracer(getStatsReporter(), "parse-library-file"); - auto *NextInput = createSourceFileForMainModule( - SourceFileKind::Library, implicitImports.kind, BufferID); - addAdditionalInitialImportsTo(NextInput, implicitImports); + auto *NextInput = + createSourceFileForMainModule(SourceFileKind::Library, BufferID); // Import resolution will lazily trigger parsing of the file. performImportResolution(*NextInput); } -bool CompilerInstance::parsePartialModulesAndLibraryFiles( - const ImplicitImports &implicitImports) { +bool CompilerInstance::parsePartialModulesAndLibraryFiles() { FrontendStatsTracer tracer(getStatsReporter(), "parse-partial-modules-and-library-files"); bool hadLoadError = false; @@ -1002,7 +912,7 @@ bool CompilerInstance::parsePartialModulesAndLibraryFiles( // Then parse all the library files. for (auto BufferID : InputSourceCodeBufferIDs) { if (BufferID != MainBufferID) { - parseLibraryFile(BufferID, implicitImports); + parseLibraryFile(BufferID); } } return hadLoadError; @@ -1077,8 +987,8 @@ void CompilerInstance::finishTypeChecking() { } SourceFile *CompilerInstance::createSourceFileForMainModule( - SourceFileKind fileKind, SourceFile::ImplicitModuleImportKind importKind, - Optional bufferID, SourceFile::ParsingOptions opts) { + SourceFileKind fileKind, Optional bufferID, + SourceFile::ParsingOptions opts) { ModuleDecl *mainModule = getMainModule(); auto isPrimary = bufferID && isPrimaryInput(*bufferID); @@ -1092,7 +1002,7 @@ SourceFile *CompilerInstance::createSourceFileForMainModule( } SourceFile *inputFile = new (*Context) - SourceFile(*mainModule, fileKind, bufferID, importKind, + SourceFile(*mainModule, fileKind, bufferID, Invocation.getLangOptions().CollectParsedToken, Invocation.getLangOptions().BuildSyntaxTree, opts); MainModule->addFile(*inputFile); @@ -1132,7 +1042,6 @@ void CompilerInstance::performParseOnly(bool EvaluateConditionals, assert(Kind == InputFileKind::Swift || Kind == InputFileKind::SwiftModuleInterface); createSourceFileForMainModule(Invocation.getSourceFileKind(), - SourceFile::ImplicitModuleImportKind::None, MainBufferID, parsingOpts); } @@ -1142,8 +1051,7 @@ void CompilerInstance::performParseOnly(bool EvaluateConditionals, continue; SourceFile *NextInput = createSourceFileForMainModule( - SourceFileKind::Library, SourceFile::ImplicitModuleImportKind::None, - BufferID, parsingOpts); + SourceFileKind::Library, BufferID, parsingOpts); // Force the parsing of the top level decls. (void)NextInput->getTopLevelDecls(); diff --git a/lib/IDE/CompletionInstance.cpp b/lib/IDE/CompletionInstance.cpp index 546aa36ffa0ce..cb3f8c965b577 100644 --- a/lib/IDE/CompletionInstance.cpp +++ b/lib/IDE/CompletionInstance.cpp @@ -208,9 +208,7 @@ bool CompletionInstance::performCachedOperationIfPossible( registerTypeCheckerRequestFunctions(tmpCtx->evaluator); registerSILGenRequestFunctions(tmpCtx->evaluator); ModuleDecl *tmpM = ModuleDecl::create(Identifier(), *tmpCtx); - SourceFile *tmpSF = - new (*tmpCtx) SourceFile(*tmpM, oldSF->Kind, tmpBufferID, - SourceFile::ImplicitModuleImportKind::None); + SourceFile *tmpSF = new (*tmpCtx) SourceFile(*tmpM, oldSF->Kind, tmpBufferID); tmpSF->enableInterfaceHash(); // Ensure all non-function-body tokens are hashed into the interface hash tmpCtx->LangOpts.EnableTypeFingerprints = false; @@ -318,12 +316,11 @@ bool CompletionInstance::performCachedOperationIfPossible( // Create a new module and a source file using the current AST context. auto &Ctx = oldM->getASTContext(); - auto newM = ModuleDecl::create(oldM->getName(), Ctx); - CompilerInstance::ImplicitImports implicitImport(CI); - SourceFile *newSF = new (Ctx) SourceFile(*newM, SourceFileKind::Main, - newBufferID, implicitImport.kind); + auto *newM = + ModuleDecl::create(oldM->getName(), Ctx, oldM->getImplicitImportInfo()); + auto *newSF = + new (Ctx) SourceFile(*newM, SourceFileKind::Main, newBufferID); newM->addFile(*newSF); - CompilerInstance::addAdditionalInitialImportsTo(newSF, implicitImport); newSF->enableInterfaceHash(); // Tell the compiler instance we've replaced the code completion file. diff --git a/lib/IDE/REPLCodeCompletion.cpp b/lib/IDE/REPLCodeCompletion.cpp index 79e49dcc7dca1..70fc52edd8e5a 100644 --- a/lib/IDE/REPLCodeCompletion.cpp +++ b/lib/IDE/REPLCodeCompletion.cpp @@ -210,34 +210,30 @@ doCodeCompletion(SourceFile &SF, StringRef EnteredCode, unsigned *BufferID, Ctx.SourceMgr.setCodeCompletionPoint(*BufferID, CodeCompletionOffset); - // Create a new module and file for the code completion buffer, similar to how - // we handle new lines of REPL input. - auto *newModule = - ModuleDecl::create(Ctx.getIdentifier("REPL_Code_Completion"), Ctx); - auto &newSF = - *new (Ctx) SourceFile(*newModule, SourceFileKind::REPL, *BufferID, - SourceFile::ImplicitModuleImportKind::None); - newModule->addFile(newSF); - // Import the last module. auto *lastModule = SF.getParentModule(); - ModuleDecl::ImportedModule importOfLastModule{/*AccessPath*/ {}, lastModule}; - newSF.addImports(SourceFile::ImportedModuleDesc(importOfLastModule, - SourceFile::ImportOptions())); + + ImplicitImportInfo implicitImports; + implicitImports.AdditionalModules.emplace_back(lastModule, + /*exported*/ false); // Carry over the private imports from the last module. SmallVector imports; lastModule->getImportedModules(imports, ModuleDecl::ImportFilterKind::Private); - if (!imports.empty()) { - SmallVector importsWithOptions; - for (auto &import : imports) { - importsWithOptions.emplace_back( - SourceFile::ImportedModuleDesc(import, SourceFile::ImportOptions())); - } - newSF.addImports(importsWithOptions); + for (auto &import : imports) { + implicitImports.AdditionalModules.emplace_back(import.second, + /*exported*/ false); } + // Create a new module and file for the code completion buffer, similar to how + // we handle new lines of REPL input. + auto *newModule = ModuleDecl::create( + Ctx.getIdentifier("REPL_Code_Completion"), Ctx, implicitImports); + auto &newSF = + *new (Ctx) SourceFile(*newModule, SourceFileKind::REPL, *BufferID); + newModule->addFile(newSF); + performImportResolution(newSF); bindExtensions(newSF); diff --git a/lib/Immediate/REPL.cpp b/lib/Immediate/REPL.cpp index b08ad619bde41..581a0885584c7 100644 --- a/lib/Immediate/REPL.cpp +++ b/lib/Immediate/REPL.cpp @@ -161,34 +161,29 @@ static void convertToUTF8(llvm::ArrayRef wide, static ModuleDecl * typeCheckREPLInput(ModuleDecl *MostRecentModule, StringRef Name, std::unique_ptr Buffer) { - using ImplicitModuleImportKind = SourceFile::ImplicitModuleImportKind; assert(MostRecentModule); ASTContext &Ctx = MostRecentModule->getASTContext(); - auto REPLModule = ModuleDecl::create(Ctx.getIdentifier(Name), Ctx); - auto BufferID = Ctx.SourceMgr.addNewSourceBuffer(std::move(Buffer)); - auto ImportKind = ImplicitModuleImportKind::None; - auto &REPLInputFile = *new (Ctx) SourceFile(*REPLModule, SourceFileKind::REPL, - BufferID, ImportKind); - REPLModule->addFile(REPLInputFile); - - ModuleDecl::ImportedModule ImportOfMostRecentModule{ - /*AccessPath*/{}, MostRecentModule}; - REPLInputFile.addImports(SourceFile::ImportedModuleDesc( - ImportOfMostRecentModule, SourceFile::ImportOptions())); + // Import the last module. + ImplicitImportInfo implicitImports; + implicitImports.AdditionalModules.emplace_back(MostRecentModule, + /*exported*/ false); - SmallVector Imports; - MostRecentModule->getImportedModules(Imports, + // Carry over the private imports from the last module. + SmallVector imports; + MostRecentModule->getImportedModules(imports, ModuleDecl::ImportFilterKind::Private); - if (!Imports.empty()) { - SmallVector ImportsWithOptions; - for (auto Import : Imports) { - ImportsWithOptions.emplace_back(SourceFile::ImportedModuleDesc( - Import, SourceFile::ImportFlags::Exported)); - } - REPLInputFile.addImports(ImportsWithOptions); + for (auto &import : imports) { + implicitImports.AdditionalModules.emplace_back(import.second, + /*exported*/ true); } + auto *REPLModule = + ModuleDecl::create(Ctx.getIdentifier(Name), Ctx, implicitImports); + auto BufferID = Ctx.SourceMgr.addNewSourceBuffer(std::move(Buffer)); + auto &REPLInputFile = + *new (Ctx) SourceFile(*REPLModule, SourceFileKind::REPL, BufferID); + REPLModule->addFile(REPLInputFile); performTypeChecking(REPLInputFile); return REPLModule; } diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 9ba7f122a18de..d3b1986dca317 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -1190,8 +1190,7 @@ struct ParserUnit::Implementation { Ctx(*ASTContext::get(LangOpts, TypeCheckerOpts, SearchPathOpts, SM, Diags)), SF(new (Ctx) SourceFile( *ModuleDecl::create(Ctx.getIdentifier(ModuleName), Ctx), SFKind, - BufferID, SourceFile::ImplicitModuleImportKind::None, - Opts.CollectParsedToken, Opts.BuildSyntaxTree, + BufferID, Opts.CollectParsedToken, Opts.BuildSyntaxTree, SourceFile::ParsingFlags::DisableDelayedBodies | SourceFile::ParsingFlags::DisablePoundIfEvaluation)) {} diff --git a/lib/Sema/ImportResolution.cpp b/lib/Sema/ImportResolution.cpp index e5865dae19288..38a85685bc1aa 100644 --- a/lib/Sema/ImportResolution.cpp +++ b/lib/Sema/ImportResolution.cpp @@ -193,7 +193,19 @@ class ImportResolver final : public DeclVisitor { size_t nextModuleToCrossImport = 0; public: - ImportResolver(SourceFile &SF) : SF(SF), ctx(SF.getASTContext()) {} + ImportResolver(SourceFile &SF) : SF(SF), ctx(SF.getASTContext()) { + addImplicitImports(); + } + + void addImplicitImports() { + // TODO: Support cross-module imports. + for (auto &import : SF.getParentModule()->getImplicitImports()) { + assert(!(SF.Kind == SourceFileKind::SIL && + import.Module->isStdlibModule())); + ImportedModule importedMod(/*accessPath*/ {}, import.Module); + boundImports.emplace_back(importedMod, import.Options); + } + } /// Retrieve the finalized imports. ArrayRef getFinishedImports() const { @@ -264,24 +276,19 @@ class ImportResolver final : public DeclVisitor { /// /// Import resolution operates on a parsed but otherwise unvalidated AST. void swift::performImportResolution(SourceFile &SF) { - FrontendStatsTracer tracer(SF.getASTContext().Stats, - "Import resolution"); - - // Make sure we skip adding the standard library imports if the - // source file is empty. - if (SF.ASTStage == SourceFile::ImportsResolved || - SF.getTopLevelDecls().empty()) { - SF.ASTStage = SourceFile::ImportsResolved; + // If we've already performed import resolution, bail. + if (SF.ASTStage == SourceFile::ImportsResolved) return; - } + FrontendStatsTracer tracer(SF.getASTContext().Stats, + "Import resolution"); ImportResolver resolver(SF); // Resolve each import declaration. for (auto D : SF.getTopLevelDecls()) resolver.visit(D); - SF.addImports(resolver.getFinishedImports()); + SF.setImports(resolver.getFinishedImports()); SF.ASTStage = SourceFile::ImportsResolved; verify(SF); @@ -399,6 +406,81 @@ UnboundImport::getTopLevelModule(ModuleDecl *M, SourceFile &SF) { return topLevelModule; } +//===----------------------------------------------------------------------===// +// MARK: Implicit imports +//===----------------------------------------------------------------------===// + +ArrayRef +ModuleImplicitImportsRequest::evaluate(Evaluator &evaluator, + ModuleDecl *module) const { + SmallVector imports; + + auto &ctx = module->getASTContext(); + auto &importInfo = module->getImplicitImportInfo(); + + // Add an implicit stdlib if needed. + switch (importInfo.StdlibKind) { + case ImplicitStdlibKind::None: + break; + case ImplicitStdlibKind::Builtin: + imports.emplace_back(ctx.TheBuiltinModule); + break; + case ImplicitStdlibKind::Stdlib: { + auto *stdlib = ctx.getStdlibModule(/*loadIfAbsent*/ true); + assert(stdlib && "Missing stdlib?"); + imports.emplace_back(stdlib); + break; + } + } + + // Add any modules we were asked to implicitly import. + for (auto moduleName : importInfo.ModuleNames) { + auto *importModule = ctx.getModule({{moduleName, SourceLoc()}}); + if (!importModule) { + ctx.Diags.diagnose(SourceLoc(), diag::sema_no_import, moduleName.str()); + if (ctx.SearchPathOpts.SDKPath.empty() && + llvm::Triple(llvm::sys::getProcessTriple()).isMacOSX()) { + ctx.Diags.diagnose(SourceLoc(), diag::sema_no_import_no_sdk); + ctx.Diags.diagnose(SourceLoc(), diag::sema_no_import_no_sdk_xcrun); + } + continue; + } + imports.emplace_back(importModule); + } + + // Add any pre-loaded modules. + for (auto &module : importInfo.AdditionalModules) { + imports.emplace_back(module.first, module.second ? ImportFlags::Exported + : ImportOptions()); + } + + auto *clangImporter = + static_cast(ctx.getClangModuleLoader()); + + // Implicitly import the bridging header module if needed. + auto bridgingHeaderPath = importInfo.BridgingHeaderPath; + if (!bridgingHeaderPath.empty() && + !clangImporter->importBridgingHeader(bridgingHeaderPath, module)) { + auto *headerModule = clangImporter->getImportedHeaderModule(); + assert(headerModule && "Didn't load bridging header?"); + imports.emplace_back(headerModule, ImportFlags::Exported); + } + + // Implicitly import the underlying Clang half of this module if needed. + if (importInfo.ShouldImportUnderlyingModule) { + auto *underlyingMod = clangImporter->loadModule( + SourceLoc(), {Located(module->getName(), SourceLoc())}); + if (underlyingMod) { + imports.emplace_back(underlyingMod, ImportFlags::Exported); + } else { + ctx.Diags.diagnose(SourceLoc(), diag::error_underlying_module_not_found, + module->getName()); + } + } + + return ctx.AllocateCopy(imports); +} + //===----------------------------------------------------------------------===// // MARK: Import validation (except for scoped imports) //===----------------------------------------------------------------------===// diff --git a/lib/Sema/SourceLoader.cpp b/lib/Sema/SourceLoader.cpp index 92d736f23c5c6..a1dfa86b9b14c 100644 --- a/lib/Sema/SourceLoader.cpp +++ b/lib/Sema/SourceLoader.cpp @@ -115,17 +115,17 @@ ModuleDecl *SourceLoader::loadModule(SourceLoc importLoc, else bufferID = Ctx.SourceMgr.addNewSourceBuffer(std::move(inputFile)); - auto *importMod = ModuleDecl::create(moduleID.Item, Ctx); + ImplicitImportInfo importInfo; + importInfo.StdlibKind = Ctx.getStdlibModule() ? ImplicitStdlibKind::Stdlib + : ImplicitStdlibKind::None; + + auto *importMod = ModuleDecl::create(moduleID.Item, Ctx, importInfo); if (EnableLibraryEvolution) importMod->setResilienceStrategy(ResilienceStrategy::Resilient); Ctx.LoadedModules[moduleID.Item] = importMod; - auto implicitImportKind = SourceFile::ImplicitModuleImportKind::Stdlib; - if (!Ctx.getStdlibModule()) - implicitImportKind = SourceFile::ImplicitModuleImportKind::None; - auto *importFile = new (Ctx) SourceFile(*importMod, SourceFileKind::Library, - bufferID, implicitImportKind, + bufferID, Ctx.LangOpts.CollectParsedToken, Ctx.LangOpts.BuildSyntaxTree); importMod->addFile(*importFile); diff --git a/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.cpp b/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.cpp index 5cd60485842d7..44cb9287a7116 100644 --- a/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.cpp +++ b/tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.cpp @@ -337,7 +337,7 @@ ImportDepth::ImportDepth(ASTContext &context, // specially by applying import depth 0. llvm::StringSet<> auxImports; for (StringRef moduleName : - invocation.getFrontendOptions().ImplicitImportModuleNames) + invocation.getFrontendOptions().getImplicitImportModuleNames()) auxImports.insert(moduleName); // Private imports from this module. diff --git a/unittests/AST/TestContext.cpp b/unittests/AST/TestContext.cpp index 49605a2fa2f19..eb2439f3bc27e 100644 --- a/unittests/AST/TestContext.cpp +++ b/unittests/AST/TestContext.cpp @@ -42,11 +42,8 @@ TestContext::TestContext(ShouldDeclareOptionalTypes optionals) auto *module = ModuleDecl::create(stdlibID, Ctx); Ctx.LoadedModules[stdlibID] = module; - using ImplicitModuleImportKind = SourceFile::ImplicitModuleImportKind; FileForLookups = new (Ctx) SourceFile(*module, SourceFileKind::Library, - /*buffer*/None, - ImplicitModuleImportKind::None, - /*keeps token*/false); + /*buffer*/ None, /*keeps token*/ false); module->addFile(*FileForLookups); if (optionals == DeclareOptionalTypes) {