Skip to content

Fix layering of cross-import and clang overlays #31199

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/swift/AST/SourceFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,8 @@ class SourceFile final : public FileUnit {
overlays.append(value.begin(), value.end());
}

SWIFT_DEBUG_DUMPER(dumpSeparatelyImportedOverlays());

void cacheVisibleDecls(SmallVectorImpl<ValueDecl *> &&globals) const;
const SmallVectorImpl<ValueDecl *> &getCachedVisibleDecls() const;

Expand Down
4 changes: 4 additions & 0 deletions lib/AST/ASTDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1259,6 +1259,10 @@ namespace {

void visitModuleDecl(ModuleDecl *MD) {
printCommon(MD, "module");

if (MD->isNonSwiftModule())
OS << " non_swift";

PrintWithColorRAII(OS, ParenthesisColor) << ')';
}

Expand Down
16 changes: 16 additions & 0 deletions lib/AST/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1430,6 +1430,22 @@ SourceFile::getImportedModules(SmallVectorImpl<ModuleDecl::ImportedModule> &modu
}
}

void SourceFile::dumpSeparatelyImportedOverlays() const {
for (auto &pair : separatelyImportedOverlays) {
auto &underlying = std::get<0>(pair);
auto &overlays = std::get<1>(pair);

llvm::errs() << (void*)underlying << " ";
underlying->dump(llvm::errs());

for (auto overlay : overlays) {
llvm::errs() << "- ";
llvm::errs() << (void*)overlay << " ";
overlay->dump(llvm::errs());
}
}
}

void ModuleDecl::getImportedModulesForLookup(
SmallVectorImpl<ImportedModule> &modules) const {
FORWARD(getImportedModulesForLookup, (modules));
Expand Down
12 changes: 10 additions & 2 deletions lib/Sema/ImportResolution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -896,9 +896,17 @@ void ImportResolver::crossImport(ModuleDecl *M, UnboundImport &I) {
if (!SF.shouldCrossImport())
return;

if (I.getUnderlyingModule())
if (I.getUnderlyingModule()) {
auto underlying = I.getUnderlyingModule().get();

// If this is a clang module, and it has a clang overlay, we want the
// separately-imported overlay to sit on top of the clang overlay.
if (underlying->isNonSwiftModule())
underlying = underlying->getTopLevelModule(true);

// FIXME: Should we warn if M doesn't reexport underlyingModule?
SF.addSeparatelyImportedOverlay(M, I.getUnderlyingModule().get());
SF.addSeparatelyImportedOverlay(M, underlying);
}

auto newImports = crossImportableModules.getArrayRef()
.drop_front(nextModuleToCrossImport);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
%YAML 1.2
---
version: 1
modules:
- name: _ClangFramework_BystandingLibrary
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
%YAML 1.2
---
version: 1
modules:
- name: _OverlaidClangFramework_BystandingLibrary
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
%YAML 1.2
---
version: 1
modules:
- name: _SwiftFramework_BystandingLibrary
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// swift-interface-format-version: 1.0
// swift-module-flags: -swift-version 5 -enable-library-evolution -module-name _ClangFramework_BystandingLibrary

import Swift
@_exported import ClangFramework

public func fromClangFrameworkCrossImport()
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// swift-interface-format-version: 1.0
// swift-module-flags: -swift-version 5 -enable-library-evolution -module-name _OverlaidClangFramework_BystandingLibrary

import Swift
@_exported import OverlaidClangFramework

public func fromOverlaidClangFrameworkCrossImport()
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// swift-interface-format-version: 1.0
// swift-module-flags: -swift-version 5 -enable-library-evolution -module-name _SwiftFramework_BystandingLibrary

import Swift
@_exported import SwiftFramework

public func fromSwiftFrameworkCrossImport()
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@

import Swift
@_exported import OverlaidClangFramework

public func fromOverlaidClangFrameworkOverlay()
40 changes: 40 additions & 0 deletions test/CrossImport/common-case.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// This explicitly tests "common" cases with well-constructed cross-import
// overlays. Some behaviors here are poorly covered by other tests.

// RUN: %empty-directory(%t)
// RUN: cp -r %S/Inputs/lib-templates/* %t/
// RUN: %{python} %S/Inputs/rewrite-module-triples.py %t %module-target-triple

// RUN: %target-typecheck-verify-swift -enable-cross-import-overlays -I %t/include -I %t/lib/swift -F %t/Frameworks

// Each framework has a cross-import overlay with this library:
import BystandingLibrary

// 1. A Swift framework

import SwiftFramework

fromSwiftFramework()
fromSwiftFrameworkCrossImport()
SwiftFramework.fromSwiftFramework()
SwiftFramework.fromSwiftFrameworkCrossImport()

// 2. A Clang framework

import ClangFramework

fromClangFramework()
fromClangFrameworkCrossImport()
ClangFramework.fromClangFramework()
ClangFramework.fromClangFrameworkCrossImport()

// 3. A Swift-overlaid Clang framework

import OverlaidClangFramework

fromOverlaidClangFramework()
fromOverlaidClangFrameworkOverlay()
fromOverlaidClangFrameworkCrossImport()
OverlaidClangFramework.fromOverlaidClangFramework()
OverlaidClangFramework.fromOverlaidClangFrameworkOverlay()
OverlaidClangFramework.fromOverlaidClangFrameworkCrossImport()