Skip to content

Commit f8df2f6

Browse files
committed
Add mechanism for per-SourceFile overlays
When a “separately imported overlay” is added to a SourceFile, two things happen: 1. The direct import of the underlying module is removed from getImports*() by default. It is only visible if the caller passes ImportFilterKind:: ShadowedBySeparateOverlay. This means that non-module-scoped lookups will search _OverlayModule before searching its re-export UnderlyingModule, allowing it to shadow underlying declarations. 2. When you ask for lookupInModule() to look in the underlying module in that source file, it looks in the overlays instead. This means that UnderlyingModule.foo() can find declarations in _OverlayModule.
1 parent e248f82 commit f8df2f6

File tree

13 files changed

+85
-6
lines changed

13 files changed

+85
-6
lines changed

include/swift/AST/DeclContext.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,14 @@ class alignas(1 << DeclContextAlignInBits) DeclContext {
578578
SmallVectorImpl<ConformanceDiagnostic> *diagnostics
579579
= nullptr) const;
580580

581+
/// Retrieves a list of separately imported overlays which are shadowing
582+
/// \p declaring. If any \p overlays are returned, qualified lookups into
583+
/// \p declaring should be performed into \p overlays instead; since they
584+
/// are overlays, they will re-export \p declaring, but will also augment it
585+
/// with additional symbols.
586+
void getSeparatelyImportedOverlays(
587+
ModuleDecl *declaring, SmallVectorImpl<ModuleDecl *> &overlays) const;
588+
581589
/// Retrieve the syntactic depth of this declaration context, i.e.,
582590
/// the number of non-module-scoped contexts.
583591
///

include/swift/AST/Module.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,11 @@ class ModuleDecl : public DeclContext, public TypeDecl {
466466
/// Include "regular" imports with no special annotation.
467467
Private = 1 << 1,
468468
/// Include imports declared with `@_implementationOnly`.
469-
ImplementationOnly = 1 << 2
469+
ImplementationOnly = 1 << 2,
470+
/// Include imports shadowed by a separately-imported overlay (i.e. a
471+
/// cross-import overlay). Unshadowed imports are included whether or not
472+
/// this flag is specified.
473+
ShadowedBySeparateOverlay = 1 << 4
470474
};
471475
/// \sa getImportedModules
472476
using ImportFilter = OptionSet<ImportFilterKind>;

include/swift/AST/SourceFile.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,17 @@ class SourceFile final : public FileUnit {
128128
/// The list of top-level declarations in the source file.
129129
std::vector<Decl *> Decls;
130130

131+
using SeparatelyImportedOverlayMap =
132+
llvm::SmallDenseMap<ModuleDecl *, llvm::SmallPtrSet<ModuleDecl *, 1>>;
133+
134+
/// Keys are modules which are shadowed by one or more separately-imported
135+
/// overlays; values are the list of overlays shadowing them.
136+
///
137+
/// This is used by cross-import overlays to make their members appear to
138+
/// be part of the underlying module. (ClangImporter overlays use a different
139+
/// mechanism which is not SourceFile-dependent.)
140+
SeparatelyImportedOverlayMap separatelyImportedOverlays;
141+
131142
friend ASTContext;
132143
friend Impl;
133144

@@ -257,6 +268,29 @@ class SourceFile final : public FileUnit {
257268

258269
bool isImportedImplementationOnly(const ModuleDecl *module) const;
259270

271+
/// Register a separately-imported overlay as shadowing the module that
272+
/// declares it.
273+
///
274+
/// \returns true if the overlay was added; false if it already existed.
275+
bool addSeparatelyImportedOverlay(ModuleDecl *overlay,
276+
ModuleDecl *declaring) {
277+
return std::get<1>(separatelyImportedOverlays[declaring].insert(overlay));
278+
}
279+
280+
/// Retrieves a list of separately imported overlays which are shadowing
281+
/// \p declaring. If any \p overlays are returned, qualified lookups into
282+
/// \p declaring should be performed into \p overlays instead; since they
283+
/// are overlays, they will re-export \p declaring, but will also augment it
284+
/// with additional symbols.
285+
void getSeparatelyImportedOverlays(
286+
ModuleDecl *declaring, SmallVectorImpl<ModuleDecl *> &overlays) {
287+
auto i = separatelyImportedOverlays.find(declaring);
288+
if (i == separatelyImportedOverlays.end()) return;
289+
290+
auto &value = std::get<1>(*i);
291+
overlays.append(value.begin(), value.end());
292+
}
293+
260294
void cacheVisibleDecls(SmallVectorImpl<ValueDecl *> &&globals) const;
261295
const SmallVectorImpl<ValueDecl *> &getCachedVisibleDecls() const;
262296

lib/AST/DeclContext.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,12 @@ DeclContext *DeclContext::getModuleScopeContext() const {
287287
}
288288
}
289289

290+
void DeclContext::getSeparatelyImportedOverlays(
291+
ModuleDecl *declaring, SmallVectorImpl<ModuleDecl *> &overlays) const {
292+
if (auto SF = getParentSourceFile())
293+
SF->getSeparatelyImportedOverlays(declaring, overlays);
294+
}
295+
290296
/// Determine whether the given context is generic at any level.
291297
bool DeclContext::isGenericContext() const {
292298
auto dc = this;

lib/AST/Module.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,15 +1162,18 @@ SourceFile::getImportedModules(SmallVectorImpl<ModuleDecl::ImportedModule> &modu
11621162
assert(ASTStage >= Parsed || Kind == SourceFileKind::SIL);
11631163
assert(filter && "no imports requested?");
11641164
for (auto desc : Imports) {
1165-
ModuleDecl::ImportFilterKind requiredKind;
1165+
ModuleDecl::ImportFilter requiredFilter;
11661166
if (desc.importOptions.contains(ImportFlags::Exported))
1167-
requiredKind = ModuleDecl::ImportFilterKind::Public;
1167+
requiredFilter |= ModuleDecl::ImportFilterKind::Public;
11681168
else if (desc.importOptions.contains(ImportFlags::ImplementationOnly))
1169-
requiredKind = ModuleDecl::ImportFilterKind::ImplementationOnly;
1169+
requiredFilter |= ModuleDecl::ImportFilterKind::ImplementationOnly;
11701170
else
1171-
requiredKind = ModuleDecl::ImportFilterKind::Private;
1171+
requiredFilter |= ModuleDecl::ImportFilterKind::Private;
11721172

1173-
if (filter.contains(requiredKind))
1173+
if (!separatelyImportedOverlays.lookup(desc.module.second).empty())
1174+
requiredFilter |= ModuleDecl::ImportFilterKind::ShadowedBySeparateOverlay;
1175+
1176+
if (filter.contains(requiredFilter))
11741177
modules.push_back(desc.module);
11751178
}
11761179
}

lib/AST/ModuleNameLookup.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,20 @@ void ModuleNameLookup<LookupStrategy>::lookupInModule(
127127
const DeclContext *moduleScopeContext) {
128128
assert(moduleOrFile->isModuleScopeContext());
129129

130+
// Does the module scope have any separately-imported overlays shadowing
131+
// the module we're looking into?
132+
SmallVector<ModuleDecl *, 4> overlays;
133+
moduleScopeContext->getSeparatelyImportedOverlays(
134+
moduleOrFile->getParentModule(), overlays);
135+
if (!overlays.empty()) {
136+
// If so, look in each of those overlays.
137+
for (auto overlay : overlays)
138+
lookupInModule(decls, overlay, accessPath, moduleScopeContext);
139+
// FIXME: This may not work gracefully if more than one of these lookups
140+
// finds something.
141+
return;
142+
}
143+
130144
const size_t initialCount = decls.size();
131145
size_t currentCount = decls.size();
132146

lib/FrontendTool/FrontendTool.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ static bool emitLoadedModuleTraceIfNeeded(ModuleDecl *mainModule,
404404
ModuleDecl::ImportFilter filter = ModuleDecl::ImportFilterKind::Public;
405405
filter |= ModuleDecl::ImportFilterKind::Private;
406406
filter |= ModuleDecl::ImportFilterKind::ImplementationOnly;
407+
filter |= ModuleDecl::ImportFilterKind::ShadowedBySeparateOverlay;
407408
SmallVector<ModuleDecl::ImportedModule, 8> imports;
408409
mainModule->getImportedModules(imports, filter);
409410

lib/IDE/CodeCompletion.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,6 +1720,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
17201720
ImportFilter |= ModuleDecl::ImportFilterKind::Public;
17211721
ImportFilter |= ModuleDecl::ImportFilterKind::Private;
17221722
ImportFilter |= ModuleDecl::ImportFilterKind::ImplementationOnly;
1723+
// FIXME: ImportFilterKind::ShadowedBySeparateOverlay?
17231724

17241725
SmallVector<ModuleDecl::ImportedModule, 16> Imported;
17251726
SmallVector<ModuleDecl::ImportedModule, 16> FurtherImported;
@@ -5648,6 +5649,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
56485649
ImportFilter |= ModuleDecl::ImportFilterKind::Public;
56495650
ImportFilter |= ModuleDecl::ImportFilterKind::Private;
56505651
ImportFilter |= ModuleDecl::ImportFilterKind::ImplementationOnly;
5652+
// FIXME: ImportFilterKind::ShadowedBySeparateOverlay?
56515653
SmallVector<ModuleDecl::ImportedModule, 4> Imports;
56525654
auto *SF = CurDeclContext->getParentSourceFile();
56535655
SF->getImportedModules(Imports, ImportFilter);

lib/Index/Index.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ class SourceFileOrModule {
129129
ImportFilter |= ModuleDecl::ImportFilterKind::Public;
130130
ImportFilter |= ModuleDecl::ImportFilterKind::Private;
131131
ImportFilter |= ModuleDecl::ImportFilterKind::ImplementationOnly;
132+
// FIXME: ImportFilterKind::ShadowedBySeparateOverlay?
132133

133134
if (auto *SF = SFOrMod.dyn_cast<SourceFile *>()) {
134135
SF->getImportedModules(Modules, ImportFilter);
@@ -1561,6 +1562,7 @@ void IndexSwiftASTWalker::collectRecursiveModuleImports(
15611562
ModuleDecl::ImportFilter ImportFilter;
15621563
ImportFilter |= ModuleDecl::ImportFilterKind::Public;
15631564
ImportFilter |= ModuleDecl::ImportFilterKind::Private;
1565+
// FIXME: ImportFilterKind::ShadowedBySeparateOverlay?
15641566
SmallVector<ModuleDecl::ImportedModule, 8> Imports;
15651567
TopMod.getImportedModules(Imports);
15661568

lib/Index/IndexRecord.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,7 @@ emitDataForSwiftSerializedModule(ModuleDecl *module,
562562
ModuleDecl::ImportFilter importFilter;
563563
importFilter |= ModuleDecl::ImportFilterKind::Public;
564564
importFilter |= ModuleDecl::ImportFilterKind::Private;
565+
// FIXME: ImportFilterKind::ShadowedBySeparateOverlay?
565566
SmallVector<ModuleDecl::ImportedModule, 8> imports;
566567
module->getImportedModules(imports, importFilter);
567568
StringScratchSpace moduleNameScratch;
@@ -602,6 +603,7 @@ recordSourceFileUnit(SourceFile *primarySourceFile, StringRef indexUnitToken,
602603
importFilter |= ModuleDecl::ImportFilterKind::Public;
603604
importFilter |= ModuleDecl::ImportFilterKind::Private;
604605
importFilter |= ModuleDecl::ImportFilterKind::ImplementationOnly;
606+
// FIXME: ImportFilterKind::ShadowedBySeparateOverlay?
605607
SmallVector<ModuleDecl::ImportedModule, 8> imports;
606608
primarySourceFile->getImportedModules(imports, importFilter);
607609
StringScratchSpace moduleNameScratch;

0 commit comments

Comments
 (0)