@@ -51,36 +51,17 @@ namespace {
51
51
// / source, or it may represent a cross-import overlay that has been found and
52
52
// / needs to be loaded.
53
53
struct UnboundImport {
54
+ // / Information about the import. Use this field, not \c getImportDecl(), to
55
+ // / determine the behavior expected for this import.
56
+ AttributedImport<UnloadedImportedModule> import ;
57
+
54
58
// / The source location to use when diagnosing errors for this import.
55
59
SourceLoc importLoc;
56
60
57
- // / The options for this import, such as "exported" or
58
- // / "implementation-only". Use this field, not \c attrs, to determine the
59
- // / behavior expected for this import.
60
- ImportOptions options;
61
-
62
- // / If \c options includes \c PrivateImport, the filename we should import
63
- // / private declarations from.
64
- StringRef sourceFileArg;
65
-
66
- // / The module names being imported. There will usually be just one for the
67
- // / top-level module, but a submodule import will have more.
68
- ImportPath::Module modulePath;
69
-
70
- // / If this is a scoped import, the names of the declaration being imported;
71
- // / otherwise empty. (Currently the compiler doesn't support nested scoped
72
- // / imports, so there should always be zero or one elements, but
73
- // / \c ImportPath::Access is the common currency type for this.)
74
- ImportPath::Access accessPath;
75
-
76
- // Names of explicitly imported SPI groups via @_spi.
77
- ArrayRef<Identifier> spiGroups;
78
-
79
61
// / If this UnboundImport directly represents an ImportDecl, contains the
80
62
// / ImportDecl it represents. This should only be used for diagnostics and
81
63
// / for updating the AST; if you want to read information about the import,
82
- // / get it from the other fields in \c UnboundImport rather than from the
83
- // / \c ImportDecl.
64
+ // / get it from the \c import field rather than from the \c ImportDecl.
84
65
// /
85
66
// / If this UnboundImport represents a cross-import, contains the declaring
86
67
// / module's \c ModuleDecl.
@@ -137,8 +118,8 @@ struct UnboundImport {
137
118
// / UnboundImport.
138
119
AttributedImport<ImportedModule>
139
120
makeAttributedImport (ModuleDecl *module ) const {
140
- return { ImportedModule{ accessPath , module },
141
- options, sourceFileArg, spiGroups };
121
+ return { ImportedModule{ import . module . getAccessPath () , module },
122
+ import . options , import . sourceFileArg , import . spiGroups };
142
123
}
143
124
144
125
private:
@@ -326,7 +307,7 @@ void ImportResolver::bindImport(UnboundImport &&I) {
326
307
return ;
327
308
}
328
309
329
- ModuleDecl *M = getModule (I.modulePath );
310
+ ModuleDecl *M = getModule (I.import . module . getModulePath () );
330
311
if (!I.checkModuleLoaded (M, SF)) {
331
312
// Can't process further. checkModuleLoaded() will have diagnosed this.
332
313
if (ID)
@@ -392,11 +373,11 @@ ImportResolver::getModule(ImportPath::Module modulePath) {
392
373
393
374
NullablePtr<ModuleDecl>
394
375
UnboundImport::getTopLevelModule (ModuleDecl *M, SourceFile &SF) {
395
- if (modulePath .size () == 1 )
376
+ if (import . module . getModulePath () .size () == 1 )
396
377
return M;
397
378
398
379
// If we imported a submodule, import the top-level module as well.
399
- Identifier topLevelName = modulePath .front ().Item ;
380
+ Identifier topLevelName = import . module . getModulePath () .front ().Item ;
400
381
ModuleDecl *topLevelModule = SF.getASTContext ().getLoadedModule (topLevelName);
401
382
402
383
if (!topLevelModule) {
@@ -496,39 +477,40 @@ ModuleImplicitImportsRequest::evaluate(Evaluator &evaluator,
496
477
497
478
// / Create an UnboundImport for a user-written import declaration.
498
479
UnboundImport::UnboundImport (ImportDecl *ID)
499
- : importLoc( ID->getLoc ()), options(), sourceFileArg( ),
500
- modulePath(ID-> getModulePath ()), accessPath(ID-> getAccessPath () ),
501
- importOrUnderlyingModuleDecl(ID)
480
+ : import(UnloadedImportedModule( ID->getImportPath (), ID->getImportKind() ),
481
+ {} ),
482
+ importLoc(ID-> getLoc ()), importOrUnderlyingModuleDecl(ID)
502
483
{
503
484
if (ID->isExported ())
504
- options |= ImportFlags::Exported;
485
+ import . options |= ImportFlags::Exported;
505
486
506
487
if (ID->getAttrs ().hasAttribute <TestableAttr>())
507
- options |= ImportFlags::Testable;
488
+ import . options |= ImportFlags::Testable;
508
489
509
490
if (ID->getAttrs ().hasAttribute <ImplementationOnlyAttr>())
510
- options |= ImportFlags::ImplementationOnly;
491
+ import . options |= ImportFlags::ImplementationOnly;
511
492
512
493
if (auto *privateImportAttr =
513
494
ID->getAttrs ().getAttribute <PrivateImportAttr>()) {
514
- options |= ImportFlags::PrivateImport;
515
- sourceFileArg = privateImportAttr->getSourceFile ();
495
+ import . options |= ImportFlags::PrivateImport;
496
+ import . sourceFileArg = privateImportAttr->getSourceFile ();
516
497
}
517
498
518
499
SmallVector<Identifier, 4 > spiGroups;
519
500
for (auto attr : ID->getAttrs ().getAttributes <SPIAccessControlAttr>()) {
520
- options |= ImportFlags::SPIAccessControl;
501
+ import . options |= ImportFlags::SPIAccessControl;
521
502
auto attrSPIs = attr->getSPIGroups ();
522
503
spiGroups.append (attrSPIs.begin (), attrSPIs.end ());
523
504
}
524
- this -> spiGroups = ID->getASTContext ().AllocateCopy (spiGroups);
505
+ import . spiGroups = ID->getASTContext ().AllocateCopy (spiGroups);
525
506
}
526
507
527
508
bool UnboundImport::checkNotTautological (const SourceFile &SF) {
528
509
// Exit early if this is not a self-import.
510
+ auto modulePath = import .module .getModulePath ();
529
511
if (modulePath.front ().Item != SF.getParentModule ()->getName () ||
530
512
// Overlays use an @_exported self-import to load their clang module.
531
- options.contains (ImportFlags::Exported) ||
513
+ import . options .contains (ImportFlags::Exported) ||
532
514
// Imports of your own submodules are allowed in cross-language libraries.
533
515
modulePath.size () != 1 ||
534
516
// SIL files self-import to get decls from the rest of the module.
@@ -555,7 +537,8 @@ bool UnboundImport::checkModuleLoaded(ModuleDecl *M, SourceFile &SF) {
555
537
ASTContext &ctx = SF.getASTContext ();
556
538
557
539
SmallString<64 > modulePathStr;
558
- llvm::interleave (modulePath, [&](ImportPath::Element elem) {
540
+ llvm::interleave (import .module .getModulePath (),
541
+ [&](ImportPath::Element elem) {
559
542
modulePathStr += elem.Item .str ();
560
543
},
561
544
[&] { modulePathStr += " ." ; });
@@ -599,24 +582,24 @@ void UnboundImport::validatePrivate(ModuleDecl *topLevelModule) {
599
582
assert (topLevelModule);
600
583
ASTContext &ctx = topLevelModule->getASTContext ();
601
584
602
- if (!options.contains (ImportFlags::PrivateImport))
585
+ if (!import . options .contains (ImportFlags::PrivateImport))
603
586
return ;
604
587
605
588
if (topLevelModule->arePrivateImportsEnabled ())
606
589
return ;
607
590
608
591
diagnoseInvalidAttr (DAK_PrivateImport, ctx.Diags ,
609
592
diag::module_not_compiled_for_private_import);
610
- sourceFileArg = StringRef ();
593
+ import . sourceFileArg = StringRef ();
611
594
}
612
595
613
596
void UnboundImport::validateImplementationOnly (ASTContext &ctx) {
614
- if (!options.contains (ImportFlags::ImplementationOnly) ||
615
- !options.contains (ImportFlags::Exported))
597
+ if (!import . options .contains (ImportFlags::ImplementationOnly) ||
598
+ !import . options .contains (ImportFlags::Exported))
616
599
return ;
617
600
618
601
// Remove one flag to maintain the invariant.
619
- options -= ImportFlags::ImplementationOnly;
602
+ import . options -= ImportFlags::ImplementationOnly;
620
603
621
604
diagnoseInvalidAttr (DAK_ImplementationOnly, ctx.Diags ,
622
605
diag::import_implementation_cannot_be_exported);
@@ -626,7 +609,7 @@ void UnboundImport::validateTestable(ModuleDecl *topLevelModule) {
626
609
assert (topLevelModule);
627
610
ASTContext &ctx = topLevelModule->getASTContext ();
628
611
629
- if (!options.contains (ImportFlags::Testable) ||
612
+ if (!import . options .contains (ImportFlags::Testable) ||
630
613
topLevelModule->isTestingEnabled () ||
631
614
topLevelModule->isNonSwiftModule () ||
632
615
!ctx.LangOpts .EnableTestableAttrRequiresTestableModule )
@@ -637,7 +620,7 @@ void UnboundImport::validateTestable(ModuleDecl *topLevelModule) {
637
620
638
621
void UnboundImport::validateResilience (NullablePtr<ModuleDecl> topLevelModule,
639
622
SourceFile &SF) {
640
- if (options.contains (ImportFlags::ImplementationOnly))
623
+ if (import . options .contains (ImportFlags::ImplementationOnly))
641
624
return ;
642
625
643
626
// Per getTopLevelModule(), we'll only get nullptr here for non-Swift modules,
@@ -650,7 +633,7 @@ void UnboundImport::validateResilience(NullablePtr<ModuleDecl> topLevelModule,
650
633
return ;
651
634
652
635
ASTContext &ctx = SF.getASTContext ();
653
- ctx.Diags .diagnose (modulePath .front ().Loc ,
636
+ ctx.Diags .diagnose (import . module . getModulePath () .front ().Loc ,
654
637
diag::module_not_compiled_with_library_evolution,
655
638
topLevelModule.get ()->getName (),
656
639
SF.getParentModule ()->getName ());
@@ -661,8 +644,8 @@ void UnboundImport::validateResilience(NullablePtr<ModuleDecl> topLevelModule,
661
644
void UnboundImport::diagnoseInvalidAttr (DeclAttrKind attrKind,
662
645
DiagnosticEngine &diags,
663
646
Diag<Identifier> diagID) {
664
- auto diag = diags.diagnose (modulePath .front ().Loc , diagID,
665
- modulePath .front ().Item );
647
+ auto diag = diags.diagnose (import . module . getModulePath () .front ().Loc , diagID,
648
+ import . module . getModulePath () .front ().Item );
666
649
667
650
auto *ID = getImportDecl ().getPtrOrNull ();
668
651
if (!ID) return ;
@@ -923,20 +906,32 @@ static bool canCrossImport(const AttributedImport<ImportedModule> &import) {
923
906
return true ;
924
907
}
925
908
909
+ static UnloadedImportedModule makeUnimportedCrossImportOverlay (
910
+ ASTContext &ctx,
911
+ Identifier overlayName,
912
+ const UnboundImport &base,
913
+ const AttributedImport<ImportedModule> &declaringImport) {
914
+ ImportPath::Builder
915
+ builder (overlayName, base.import .module .getModulePath ()[0 ].Loc );
916
+
917
+ // If the declaring import was scoped, inherit that scope in the overlay's
918
+ // import.
919
+ llvm::copy (declaringImport.module .accessPath , std::back_inserter (builder));
920
+
921
+ // Cross-imports are not backed by an ImportDecl, so we need to provide
922
+ // our own storage for their module paths.
923
+ return UnloadedImportedModule (builder.copyTo (ctx),
924
+ /* isScoped=*/ !declaringImport.module .accessPath .empty ());
925
+ }
926
+
926
927
// / Create an UnboundImport for a cross-import overlay.
927
928
UnboundImport::UnboundImport (
928
929
ASTContext &ctx, const UnboundImport &base, Identifier overlayName,
929
930
const AttributedImport<ImportedModule> &declaringImport,
930
931
const AttributedImport<ImportedModule> &bystandingImport)
931
- : importLoc(base.importLoc), options(), sourceFileArg(),
932
- // Cross-imports are not backed by an ImportDecl, so we need to provide
933
- // our own storage for their module paths.
934
- modulePath(
935
- ImportPath::Module::Builder (overlayName, base.modulePath[0 ].Loc)
936
- .copyTo(ctx)),
937
- // If the declaring import was scoped, inherit that scope in the
938
- // overlay's import.
939
- accessPath(declaringImport.module .accessPath),
932
+ : import(makeUnimportedCrossImportOverlay(ctx, overlayName, base,
933
+ declaringImport), {}),
934
+ importLoc(base.importLoc),
940
935
importOrUnderlyingModuleDecl(declaringImport.module .importedModule)
941
936
{
942
937
// A cross-import is never private or testable, and never comes from a private
@@ -950,13 +945,13 @@ UnboundImport::UnboundImport(
950
945
// If both are exported, the cross-import is exported.
951
946
if (declaringOptions.contains (ImportFlags::Exported) &&
952
947
bystandingOptions.contains (ImportFlags::Exported))
953
- options |= ImportFlags::Exported;
948
+ import . options |= ImportFlags::Exported;
954
949
955
950
// If either are implementation-only, the cross-import is
956
951
// implementation-only.
957
952
if (declaringOptions.contains (ImportFlags::ImplementationOnly) ||
958
953
bystandingOptions.contains (ImportFlags::ImplementationOnly))
959
- options |= ImportFlags::ImplementationOnly;
954
+ import . options |= ImportFlags::ImplementationOnly;
960
955
}
961
956
962
957
void ImportResolver::crossImport (ModuleDecl *M, UnboundImport &I) {
@@ -1107,7 +1102,7 @@ void ImportResolver::findCrossImports(
1107
1102
name);
1108
1103
1109
1104
LLVM_DEBUG ({
1110
- auto &crossImportOptions = unboundImports.back ().options ;
1105
+ auto &crossImportOptions = unboundImports.back ().import . options ;
1111
1106
llvm::dbgs () << " " ;
1112
1107
if (crossImportOptions.contains (ImportFlags::Exported))
1113
1108
llvm::dbgs () << " @_exported " ;
0 commit comments