Skip to content

Commit 7f8a0e8

Browse files
committed
Requestify implicit imports
Add ModuleImplicitImportsRequest, which computes the modules that should be implicitly imported by each file of a given module. Use this request in import resolution to add all the necessary implicit imports. The request computes the implicit imports by consulting the ImplicitImportInfo, which ModuleDecl can now be created with. This allows us to remove uses of `SourceFile::addImports` in favor of adding modules needed to be implicitly imported to the ImplicitImportInfo.
1 parent 453667f commit 7f8a0e8

19 files changed

+334
-295
lines changed

include/swift/AST/ASTTypeIDZone.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ SWIFT_TYPEID(AncestryFlags)
1919
SWIFT_TYPEID(CtorInitializerKind)
2020
SWIFT_TYPEID(FunctionBuilderBodyPreCheck)
2121
SWIFT_TYPEID(GenericSignature)
22+
SWIFT_TYPEID(ImplicitImport)
2223
SWIFT_TYPEID(ImplicitMemberAction)
2324
SWIFT_TYPEID(ParamSpecifier)
2425
SWIFT_TYPEID(PropertyWrapperBackingPropertyInfo)

include/swift/AST/ASTTypeIDs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class GenericTypeParamType;
3636
class InfixOperatorDecl;
3737
class IterableDeclContext;
3838
class ModuleDecl;
39+
struct ImplicitImport;
3940
class NamedPattern;
4041
class NominalTypeDecl;
4142
class OperatorDecl;

include/swift/AST/DiagnosticsCommon.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ ERROR(attr_only_on_parameters, none,
9090
ERROR(function_type_no_parens,none,
9191
"single argument function types require parentheses", ())
9292

93+
// Used by both the Frontend and Sema.
94+
ERROR(error_underlying_module_not_found,none,
95+
"underlying Objective-C module %0 not found", (Identifier))
96+
9397
// Used by -verify-generic-signatures
9498
ERROR(generic_signature_not_minimal,none,
9599
"generic requirement '%0' is redundant in %1", (StringRef, StringRef))

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,6 @@ ERROR(error_stdlib_module_name,none,
138138

139139
ERROR(error_stdlib_not_found,Fatal,
140140
"unable to load standard library for target '%0'", (StringRef))
141-
ERROR(error_underlying_module_not_found,none,
142-
"underlying Objective-C module %0 not found", (Identifier))
143141

144142
ERROR(error_unable_to_load_supplementary_output_file_map, none,
145143
"unable to load supplementary output file map '%0': %1",

include/swift/AST/Module.h

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ namespace swift {
5959
class FuncDecl;
6060
class InfixOperatorDecl;
6161
class LinkLibrary;
62+
struct ImplicitImport;
6263
class ModuleLoader;
6364
class NominalTypeDecl;
6465
class EnumElementDecl;
@@ -158,6 +159,42 @@ enum class ResilienceStrategy : unsigned {
158159
Resilient
159160
};
160161

162+
/// The kind of stdlib that should be imported.
163+
enum class ImplicitStdlibKind {
164+
/// No standard library should be implicitly imported.
165+
None,
166+
167+
/// The Builtin module should be implicitly imported.
168+
Builtin,
169+
170+
/// The regular Swift standard library should be implicitly imported.
171+
Stdlib
172+
};
173+
174+
struct ImplicitImportInfo {
175+
/// The implicit stdlib to import.
176+
ImplicitStdlibKind StdlibKind;
177+
178+
/// Whether we should attempt to import an underlying Clang half of this
179+
/// module.
180+
bool ShouldImportUnderlyingModule;
181+
182+
/// The bridging header path for this module, empty if there is none.
183+
StringRef BridgingHeaderPath;
184+
185+
/// The names of additional modules to be implicitly imported.
186+
SmallVector<Identifier, 4> ModuleNames;
187+
188+
/// An additional list of already-loaded modules which should be implicitly
189+
/// imported.
190+
SmallVector<std::pair<ModuleDecl *, /*exported*/ bool>, 4>
191+
AdditionalModules;
192+
193+
ImplicitImportInfo()
194+
: StdlibKind(ImplicitStdlibKind::None),
195+
ShouldImportUnderlyingModule(false) {}
196+
};
197+
161198
class OverlayFile;
162199

163200
/// The minimum unit of compilation.
@@ -245,6 +282,10 @@ class ModuleDecl : public DeclContext, public TypeDecl {
245282
llvm::SmallDenseMap<Identifier, SmallVector<OverlayFile *, 1>>
246283
declaredCrossImports;
247284

285+
/// A description of what should be implicitly imported by each file of this
286+
/// module.
287+
const ImplicitImportInfo ImportInfo;
288+
248289
std::unique_ptr<SourceLookupCache> Cache;
249290
SourceLookupCache &getSourceLookupCache() const;
250291

@@ -274,15 +315,29 @@ class ModuleDecl : public DeclContext, public TypeDecl {
274315
/// \see EntryPointInfoTy
275316
EntryPointInfoTy EntryPointInfo;
276317

277-
ModuleDecl(Identifier name, ASTContext &ctx);
318+
ModuleDecl(Identifier name, ASTContext &ctx, ImplicitImportInfo importInfo);
278319

279320
public:
280-
static ModuleDecl *create(Identifier name, ASTContext &ctx) {
281-
return new (ctx) ModuleDecl(name, ctx);
321+
/// Creates a new module with a given \p name.
322+
///
323+
/// \param importInfo Information about which modules should be implicitly
324+
/// imported by each file of this module.
325+
static ModuleDecl *
326+
create(Identifier name, ASTContext &ctx,
327+
ImplicitImportInfo importInfo = ImplicitImportInfo()) {
328+
return new (ctx) ModuleDecl(name, ctx, importInfo);
282329
}
283330

284331
using Decl::getASTContext;
285332

333+
/// Retrieves information about which modules are implicitly imported by
334+
/// each file of this module.
335+
const ImplicitImportInfo &getImplicitImportInfo() const { return ImportInfo; }
336+
337+
/// Retrieve a list of modules that each file of this module implicitly
338+
/// imports.
339+
ArrayRef<ImplicitImport> getImplicitImports() const;
340+
286341
ArrayRef<FileUnit *> getFiles() {
287342
return Files;
288343
}

include/swift/AST/SourceFile.h

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,6 @@ class SourceFile final : public FileUnit {
3333
class Impl;
3434
struct SourceFileSyntaxInfo;
3535

36-
/// The implicit module import that the SourceFile should get.
37-
enum class ImplicitModuleImportKind {
38-
None,
39-
Builtin,
40-
Stdlib
41-
};
42-
4336
/// Possible attributes for imports in source files.
4437
enum class ImportFlags {
4538
/// The imported module is exposed to anyone who imports the parent module.
@@ -335,8 +328,8 @@ class SourceFile final : public FileUnit {
335328
llvm::StringMap<SourceFilePathInfo> getInfoForUsedFilePaths() const;
336329

337330
SourceFile(ModuleDecl &M, SourceFileKind K, Optional<unsigned> bufferID,
338-
ImplicitModuleImportKind ModImpKind, bool KeepParsedTokens = false,
339-
bool KeepSyntaxTree = false, ParsingOptions parsingOpts = {});
331+
bool KeepParsedTokens = false, bool KeepSyntaxTree = false,
332+
ParsingOptions parsingOpts = {});
340333

341334
~SourceFile();
342335

include/swift/AST/TypeCheckRequests.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "swift/AST/Evaluator.h"
2424
#include "swift/AST/Pattern.h"
2525
#include "swift/AST/SimpleRequest.h"
26+
#include "swift/AST/SourceFile.h"
2627
#include "swift/AST/TypeResolutionStage.h"
2728
#include "swift/Basic/AnyValue.h"
2829
#include "swift/Basic/Statistic.h"
@@ -2344,6 +2345,45 @@ class SimpleDidSetRequest
23442345
}
23452346
};
23462347

2348+
/// A module which has been implicitly imported.
2349+
struct ImplicitImport {
2350+
using ImportOptions = SourceFile::ImportOptions;
2351+
2352+
ModuleDecl *Module;
2353+
ImportOptions Options;
2354+
2355+
ImplicitImport(ModuleDecl *module, ImportOptions opts = {})
2356+
: Module(module), Options(opts) {}
2357+
2358+
friend bool operator==(const ImplicitImport &lhs,
2359+
const ImplicitImport &rhs) {
2360+
return lhs.Module == rhs.Module &&
2361+
lhs.Options.toRaw() == rhs.Options.toRaw();
2362+
}
2363+
};
2364+
2365+
void simple_display(llvm::raw_ostream &out, const ImplicitImport &import);
2366+
2367+
/// Computes the loaded modules that should be implicitly imported by each file
2368+
/// of a given module.
2369+
class ModuleImplicitImportsRequest
2370+
: public SimpleRequest<ModuleImplicitImportsRequest,
2371+
ArrayRef<ImplicitImport>(ModuleDecl *),
2372+
RequestFlags::Cached> {
2373+
public:
2374+
using SimpleRequest::SimpleRequest;
2375+
2376+
private:
2377+
friend SimpleRequest;
2378+
2379+
ArrayRef<ImplicitImport>
2380+
evaluate(Evaluator &evaluator, ModuleDecl *module) const;
2381+
2382+
public:
2383+
// Cached.
2384+
bool isCached() const { return true; }
2385+
};
2386+
23472387
// Allow AnyValue to compare two Type values, even though Type doesn't
23482388
// support ==.
23492389
template<>

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ SWIFT_REQUEST(TypeChecker, ValidatePrecedenceGroupRequest,
128128
Cached, NoLocationInfo)
129129
SWIFT_REQUEST(TypeChecker, MangleLocalTypeDeclRequest,
130130
std::string(const TypeDecl *), Cached, NoLocationInfo)
131+
SWIFT_REQUEST(TypeChecker, ModuleImplicitImportsRequest,
132+
ArrayRef<ImplicitImport>(ModuleDecl *), Cached, NoLocationInfo)
131133
SWIFT_REQUEST(TypeChecker, NamingPatternRequest,
132134
NamedPattern *(VarDecl *), SeparatelyCached, NoLocationInfo)
133135
SWIFT_REQUEST(TypeChecker, OpaqueReadOwnershipRequest,

include/swift/Frontend/Frontend.h

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -335,14 +335,15 @@ class CompilerInvocation {
335335
/// in generating a cached PCH file for the bridging header.
336336
std::string getPCHHash() const;
337337

338-
SourceFile::ImplicitModuleImportKind getImplicitModuleImportKind() const {
338+
/// Retrieve the stdlib kind to implicitly import.
339+
ImplicitStdlibKind getImplicitStdlibKind() const {
339340
if (getInputKind() == InputFileKind::SIL) {
340-
return SourceFile::ImplicitModuleImportKind::None;
341+
return ImplicitStdlibKind::None;
341342
}
342343
if (getParseStdlib()) {
343-
return SourceFile::ImplicitModuleImportKind::Builtin;
344+
return ImplicitStdlibKind::Builtin;
344345
}
345-
return SourceFile::ImplicitModuleImportKind::Stdlib;
346+
return ImplicitStdlibKind::Stdlib;
346347
}
347348

348349
/// Performs input setup common to these tools:
@@ -654,7 +655,6 @@ class CompilerInstance {
654655
private:
655656
SourceFile *
656657
createSourceFileForMainModule(SourceFileKind FileKind,
657-
SourceFile::ImplicitModuleImportKind ImportKind,
658658
Optional<unsigned> BufferID,
659659
SourceFile::ParsingOptions options = {});
660660

@@ -667,38 +667,17 @@ class CompilerInstance {
667667
private:
668668
/// Load stdlib & return true if should continue, i.e. no error
669669
bool loadStdlib();
670-
ModuleDecl *importUnderlyingModule();
671-
ModuleDecl *importBridgingHeader();
672670

673-
void
674-
getImplicitlyImportedModules(SmallVectorImpl<ModuleDecl *> &importModules);
675-
676-
public: // for static functions in Frontend.cpp
677-
struct ImplicitImports {
678-
SourceFile::ImplicitModuleImportKind kind;
679-
ModuleDecl *objCModuleUnderlyingMixedFramework;
680-
ModuleDecl *headerModule;
681-
SmallVector<ModuleDecl *, 4> modules;
682-
683-
explicit ImplicitImports(CompilerInstance &compiler);
684-
};
685-
686-
static void addAdditionalInitialImportsTo(
687-
SourceFile *SF, const ImplicitImports &implicitImports);
688-
689-
private:
690-
void addMainFileToModule(const ImplicitImports &implicitImports);
671+
/// Retrieve a description of which modules should be implicitly imported.
672+
ImplicitImportInfo getImplicitImportInfo() const;
691673

692674
void performSemaUpTo(SourceFile::ASTStage_t LimitStage);
693-
void parseAndCheckTypesUpTo(const ImplicitImports &implicitImports,
694-
SourceFile::ASTStage_t LimitStage);
675+
void parseAndCheckTypesUpTo(SourceFile::ASTStage_t LimitStage);
695676

696-
void parseLibraryFile(unsigned BufferID,
697-
const ImplicitImports &implicitImports);
677+
void parseLibraryFile(unsigned BufferID);
698678

699679
/// Return true if had load error
700-
bool
701-
parsePartialModulesAndLibraryFiles(const ImplicitImports &implicitImports);
680+
bool parsePartialModulesAndLibraryFiles();
702681

703682
void forEachFileToTypeCheck(llvm::function_ref<void(SourceFile &)> fn);
704683

lib/AST/Module.cpp

Lines changed: 12 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -464,9 +464,11 @@ void SourceLookupCache::invalidate() {
464464
// Module Implementation
465465
//===----------------------------------------------------------------------===//
466466

467-
ModuleDecl::ModuleDecl(Identifier name, ASTContext &ctx)
468-
: DeclContext(DeclContextKind::Module, nullptr),
469-
TypeDecl(DeclKind::Module, &ctx, name, SourceLoc(), { }) {
467+
ModuleDecl::ModuleDecl(Identifier name, ASTContext &ctx,
468+
ImplicitImportInfo importInfo)
469+
: DeclContext(DeclContextKind::Module, nullptr),
470+
TypeDecl(DeclKind::Module, &ctx, name, SourceLoc(), {}),
471+
ImportInfo(importInfo) {
470472

471473
ctx.addDestructorCleanup(*this);
472474
setImplicit();
@@ -475,6 +477,13 @@ ModuleDecl::ModuleDecl(Identifier name, ASTContext &ctx)
475477
setAccess(AccessLevel::Public);
476478
}
477479

480+
ArrayRef<ImplicitImport> ModuleDecl::getImplicitImports() const {
481+
auto &evaluator = getASTContext().evaluator;
482+
auto *mutableThis = const_cast<ModuleDecl *>(this);
483+
return evaluateOrDefault(evaluator, ModuleImplicitImportsRequest{mutableThis},
484+
{});
485+
}
486+
478487
bool ModuleDecl::isClangModule() const {
479488
return findUnderlyingClangModule() != nullptr;
480489
}
@@ -2245,36 +2254,6 @@ SourceFile::getCachedVisibleDecls() const {
22452254
return getCache().AllVisibleValues;
22462255
}
22472256

2248-
static void performAutoImport(
2249-
SourceFile &SF,
2250-
SourceFile::ImplicitModuleImportKind implicitModuleImportKind) {
2251-
if (SF.Kind == SourceFileKind::SIL)
2252-
assert(implicitModuleImportKind ==
2253-
SourceFile::ImplicitModuleImportKind::None);
2254-
2255-
ASTContext &Ctx = SF.getASTContext();
2256-
ModuleDecl *M = nullptr;
2257-
2258-
switch (implicitModuleImportKind) {
2259-
case SourceFile::ImplicitModuleImportKind::None:
2260-
return;
2261-
case SourceFile::ImplicitModuleImportKind::Builtin:
2262-
M = Ctx.TheBuiltinModule;
2263-
break;
2264-
case SourceFile::ImplicitModuleImportKind::Stdlib:
2265-
M = Ctx.getStdlibModule(true);
2266-
break;
2267-
}
2268-
2269-
assert(M && "unable to auto-import module");
2270-
2271-
// FIXME: These will be the same for most source files, but we copy them
2272-
// over and over again.
2273-
auto Imports = SourceFile::ImportedModuleDesc(
2274-
ModuleDecl::ImportedModule({}, M), SourceFile::ImportOptions());
2275-
SF.addImports(Imports);
2276-
}
2277-
22782257
llvm::StringMap<SourceFilePathInfo>
22792258
SourceFile::getInfoForUsedFilePaths() const {
22802259
llvm::StringMap<SourceFilePathInfo> result;
@@ -2415,14 +2394,12 @@ ModuleDecl::computeMagicFileStringMap(bool shouldDiagnose) const {
24152394

24162395
SourceFile::SourceFile(ModuleDecl &M, SourceFileKind K,
24172396
Optional<unsigned> bufferID,
2418-
ImplicitModuleImportKind ModImpKind,
24192397
bool KeepParsedTokens, bool BuildSyntaxTree,
24202398
ParsingOptions parsingOpts)
24212399
: FileUnit(FileUnitKind::Source, M), BufferID(bufferID ? *bufferID : -1),
24222400
ParsingOpts(parsingOpts), Kind(K),
24232401
SyntaxInfo(new SourceFileSyntaxInfo(BuildSyntaxTree)) {
24242402
M.getASTContext().addDestructorCleanup(*this);
2425-
performAutoImport(*this, ModImpKind);
24262403

24272404
if (isScriptMode()) {
24282405
bool problem = M.registerEntryPointFile(this, SourceLoc(), None);

0 commit comments

Comments
 (0)