@@ -65,11 +65,12 @@ struct UnboundImport {
65
65
// /
66
66
// / If this UnboundImport represents a cross-import, contains the declaring
67
67
// / module's \c ModuleDecl.
68
- PointerUnion<ImportDecl *, ModuleDecl *> importOrUnderlyingModuleDecl;
68
+ PointerUnion<NullablePtr<ImportDecl>, ModuleDecl *>
69
+ importOrUnderlyingModuleDecl;
69
70
70
71
NullablePtr<ImportDecl> getImportDecl () const {
71
- return importOrUnderlyingModuleDecl.is <ImportDecl * >() ?
72
- importOrUnderlyingModuleDecl.get <ImportDecl * >() : nullptr ;
72
+ return importOrUnderlyingModuleDecl.is <NullablePtr< ImportDecl> >() ?
73
+ importOrUnderlyingModuleDecl.get <NullablePtr< ImportDecl> >() : nullptr ;
73
74
}
74
75
75
76
NullablePtr<ModuleDecl> getUnderlyingModule () const {
@@ -80,6 +81,9 @@ struct UnboundImport {
80
81
// / Create an UnboundImport for a user-written import declaration.
81
82
explicit UnboundImport (ImportDecl *ID);
82
83
84
+ // / Create an UnboundImport for an unloaded implicit import.
85
+ explicit UnboundImport (AttributedImport<UnloadedImportedModule> implicit);
86
+
83
87
// / Create an UnboundImport for a cross-import overlay.
84
88
explicit UnboundImport (ASTContext &ctx,
85
89
const UnboundImport &base, Identifier overlayName,
@@ -192,6 +196,9 @@ class ImportResolver final : public DeclVisitor<ImportResolver> {
192
196
return ctx.Diags .diagnose (std::forward<ArgTypes>(Args)...);
193
197
}
194
198
199
+ // / Calls \c bindImport() on unbound imports until \c boundImports is drained.
200
+ void bindPendingImports ();
201
+
195
202
// / Check a single unbound import, bind it, add it to \c boundImports,
196
203
// / and add its cross-import overlays to \c unboundImports.
197
204
void bindImport (UnboundImport &&I);
@@ -284,6 +291,10 @@ void ImportResolver::visitImportDecl(ImportDecl *ID) {
284
291
assert (unboundImports.empty ());
285
292
286
293
unboundImports.emplace_back (ID);
294
+ bindPendingImports ();
295
+ }
296
+
297
+ void ImportResolver::bindPendingImports () {
287
298
while (!unboundImports.empty ())
288
299
bindImport (unboundImports.pop_back_val ());
289
300
}
@@ -336,14 +347,16 @@ void ImportResolver::addImport(const UnboundImport &I, ModuleDecl *M) {
336
347
// MARK: Import module loading
337
348
// ===----------------------------------------------------------------------===//
338
349
339
- ModuleDecl *
340
- ImportResolver::getModule (ImportPath::Module modulePath) {
350
+ static ModuleDecl *
351
+ getModuleImpl (ImportPath::Module modulePath, ModuleDecl *loadingModule,
352
+ bool canImportBuiltin) {
353
+ ASTContext &ctx = loadingModule->getASTContext ();
354
+
341
355
assert (!modulePath.empty ());
342
356
auto moduleID = modulePath[0 ];
343
357
344
358
// The Builtin module cannot be explicitly imported unless we're a .sil file.
345
- if (SF.Kind == SourceFileKind::SIL &&
346
- moduleID.Item == ctx.TheBuiltinModule ->getName ())
359
+ if (canImportBuiltin && moduleID.Item == ctx.TheBuiltinModule ->getName ())
347
360
return ctx.TheBuiltinModule ;
348
361
349
362
// If the imported module name is the same as the current module,
@@ -352,8 +365,7 @@ ImportResolver::getModule(ImportPath::Module modulePath) {
352
365
//
353
366
// FIXME: We'd like to only use this in SIL mode, but unfortunately we use it
354
367
// for clang overlays as well.
355
- if (moduleID.Item == SF.getParentModule ()->getName () &&
356
- modulePath.size () == 1 ) {
368
+ if (moduleID.Item == loadingModule->getName () && modulePath.size () == 1 ) {
357
369
if (auto importer = ctx.getClangModuleLoader ())
358
370
return importer->loadModule (moduleID.Loc , modulePath);
359
371
return nullptr ;
@@ -362,6 +374,12 @@ ImportResolver::getModule(ImportPath::Module modulePath) {
362
374
return ctx.getModule (modulePath);
363
375
}
364
376
377
+ ModuleDecl *
378
+ ImportResolver::getModule (ImportPath::Module modulePath) {
379
+ return getModuleImpl (modulePath, SF.getParentModule (),
380
+ /* canImportBuiltin=*/ SF.Kind == SourceFileKind::SIL);
381
+ }
382
+
365
383
NullablePtr<ModuleDecl>
366
384
UnboundImport::getTopLevelModule (ModuleDecl *M, SourceFile &SF) {
367
385
if (import .module .getModulePath ().size () == 1 )
@@ -391,16 +409,25 @@ UnboundImport::getTopLevelModule(ModuleDecl *M, SourceFile &SF) {
391
409
// MARK: Implicit imports
392
410
// ===----------------------------------------------------------------------===//
393
411
394
- static void diagnoseNoSuchModule (ASTContext &ctx, SourceLoc importLoc,
412
+ static void diagnoseNoSuchModule (ModuleDecl *importingModule,
413
+ SourceLoc importLoc,
395
414
ImportPath::Module modulePath,
396
415
bool nonfatalInREPL) {
397
- SmallString<64 > modulePathStr;
398
- modulePath.getString (modulePathStr);
399
-
400
- auto diagKind = diag::sema_no_import;
401
- if (nonfatalInREPL && ctx.LangOpts .DebuggerSupport )
402
- diagKind = diag::sema_no_import_repl;
403
- ctx.Diags .diagnose (importLoc, diagKind, modulePathStr);
416
+ ASTContext &ctx = importingModule->getASTContext ();
417
+
418
+ if (modulePath.size () == 1 &&
419
+ importingModule->getName () == modulePath.front ().Item ) {
420
+ ctx.Diags .diagnose (importLoc, diag::error_underlying_module_not_found,
421
+ importingModule->getName ());
422
+ } else {
423
+ SmallString<64 > modulePathStr;
424
+ modulePath.getString (modulePathStr);
425
+
426
+ auto diagKind = diag::sema_no_import;
427
+ if (nonfatalInREPL && ctx.LangOpts .DebuggerSupport )
428
+ diagKind = diag::sema_no_import_repl;
429
+ ctx.Diags .diagnose (importLoc, diagKind, modulePathStr);
430
+ }
404
431
405
432
if (ctx.SearchPathOpts .SDKPath .empty () &&
406
433
llvm::Triple (llvm::sys::getProcessTriple ()).isMacOSX ()) {
@@ -413,6 +440,7 @@ ImplicitImportList
413
440
ModuleImplicitImportsRequest::evaluate (Evaluator &evaluator,
414
441
ModuleDecl *module ) const {
415
442
SmallVector<AttributedImport<ImportedModule>, 4 > imports;
443
+ SmallVector<AttributedImport<UnloadedImportedModule>, 4 > unloadedImports;
416
444
417
445
auto &ctx = module ->getASTContext ();
418
446
auto &importInfo = module ->getImplicitImportInfo ();
@@ -436,16 +464,8 @@ ModuleImplicitImportsRequest::evaluate(Evaluator &evaluator,
436
464
imports.emplace_back (ImportedModule (stdlib));
437
465
438
466
// Add any modules we were asked to implicitly import.
439
- for (auto unloadedImport : importInfo.AdditionalUnloadedImports ) {
440
- auto *importModule = ctx.getModule (unloadedImport.module .getModulePath ());
441
- if (!importModule) {
442
- diagnoseNoSuchModule (ctx, SourceLoc (),
443
- unloadedImport.module .getModulePath (),
444
- /* nonfatalInREPL=*/ false );
445
- continue ;
446
- }
447
- imports.push_back (unloadedImport.getLoaded (importModule));
448
- }
467
+ llvm::copy (importInfo.AdditionalUnloadedImports ,
468
+ std::back_inserter (unloadedImports));
449
469
450
470
// Add any pre-loaded modules.
451
471
llvm::copy (importInfo.AdditionalImports , std::back_inserter (imports));
@@ -464,18 +484,15 @@ ModuleImplicitImportsRequest::evaluate(Evaluator &evaluator,
464
484
465
485
// Implicitly import the underlying Clang half of this module if needed.
466
486
if (importInfo.ShouldImportUnderlyingModule ) {
467
- auto *underlyingMod = clangImporter->loadModule (
468
- SourceLoc (), ImportPath::Module::Builder (module ->getName ()).get ());
469
- if (underlyingMod) {
470
- imports.emplace_back (ImportedModule (underlyingMod),
471
- ImportFlags::Exported);
472
- } else {
473
- ctx.Diags .diagnose (SourceLoc (), diag::error_underlying_module_not_found,
474
- module ->getName ());
475
- }
487
+ // An @_exported self-import is loaded from ClangImporter instead of being
488
+ // rejected; see the special case in getModuleImpl() for details.
489
+ ImportPath::Builder importPath (module ->getName ());
490
+ unloadedImports.emplace_back (UnloadedImportedModule (importPath.copyTo (ctx),
491
+ /* isScoped=*/ false ),
492
+ ImportFlags::Exported);
476
493
}
477
494
478
- return { ctx.AllocateCopy (imports) };
495
+ return { ctx.AllocateCopy (imports), ctx. AllocateCopy (unloadedImports) };
479
496
}
480
497
481
498
void ImportResolver::addImplicitImports () {
@@ -487,8 +504,17 @@ void ImportResolver::addImplicitImports() {
487
504
import .module .importedModule ->isStdlibModule ()));
488
505
boundImports.push_back (import );
489
506
}
507
+
508
+ for (auto &unloadedImport : implicitImports.unloadedImports )
509
+ unboundImports.emplace_back (unloadedImport);
510
+
511
+ bindPendingImports ();
490
512
}
491
513
514
+ UnboundImport::UnboundImport (AttributedImport<UnloadedImportedModule> implicit)
515
+ : import(implicit), importLoc(),
516
+ importOrUnderlyingModuleDecl(static_cast <ImportDecl *>(nullptr )) {}
517
+
492
518
// ===----------------------------------------------------------------------===//
493
519
// MARK: Import validation (except for scoped imports)
494
520
// ===----------------------------------------------------------------------===//
@@ -552,7 +578,7 @@ bool UnboundImport::checkModuleLoaded(ModuleDecl *M, SourceFile &SF) {
552
578
if (M)
553
579
return true ;
554
580
555
- diagnoseNoSuchModule (SF.getASTContext (), importLoc,
581
+ diagnoseNoSuchModule (SF.getParentModule (), importLoc,
556
582
import .module .getModulePath (), /* nonfatalInREPL=*/ true );
557
583
return false ;
558
584
}
0 commit comments