Skip to content

Commit c9a6266

Browse files
committed
[ClangImporter] add implicit import of Swift for __ObjC module
Any safe wrapper expansion originating in a bridging header would fail typechecking because the `__ObjC` module doesn't import the standard implicit imports. This is because the main module is not available to inherit implicit imports from when the `__ObjC` module is created. We don't need all of the implicit modules for safe wrappers, so import `Swift` specifically. rdar://163078116
1 parent f095990 commit c9a6266

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1565,9 +1565,25 @@ std::unique_ptr<ClangImporter> ClangImporter::create(
15651565
importer->Impl.setObjectForKeyedSubscript
15661566
= clangContext.Selectors.getSelector(2, setObjectForKeyedSubscriptIdents);
15671567

1568+
ImplicitImportInfo implicitImportInfo;
1569+
// Can't inherit implicit modules from main module, because it isn't loaded yet.
1570+
// Add the Swift module, because it is important for safe interop wrappers.
1571+
if (auto stdlib = importer->Impl.getStdlibModule())
1572+
implicitImportInfo.AdditionalImports.emplace_back(ImportedModule(stdlib));
1573+
else {
1574+
Identifier stdlibName = importer->Impl.SwiftContext.getIdentifier(STDLIB_NAME);
1575+
ImportPath::Raw path =
1576+
importer->Impl.SwiftContext.AllocateCopy<Located<Identifier>>(
1577+
Located<Identifier>(stdlibName, SourceLoc()));
1578+
implicitImportInfo.AdditionalUnloadedImports.emplace_back(
1579+
UnloadedImportedModule(
1580+
ImportPath(path),
1581+
ImportKind::Module));
1582+
}
1583+
15681584
// Set up the imported header module.
15691585
auto *importedHeaderModule = ModuleDecl::create(
1570-
ctx.getIdentifier(CLANG_HEADER_MODULE_NAME), ctx,
1586+
ctx.getIdentifier(CLANG_HEADER_MODULE_NAME), ctx, implicitImportInfo,
15711587
[&](ModuleDecl *importedHeaderModule, auto addFile) {
15721588
importer->Impl.ImportedHeaderUnit = new (ctx)
15731589
ClangModuleUnit(*importedHeaderModule, importer->Impl, nullptr);
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend -typecheck -plugin-path %swift-plugin-dir -o %t/test.swiftmodule -I %t -import-objc-header %t/bridging.h -enable-experimental-feature SafeInteropWrappers -strict-memory-safety -warnings-as-errors -Xcc -Werror -Xcc -Wno-nullability-completeness -Xcc -Wno-div-by-zero -Xcc -Wno-pointer-to-int-cast %t/test.swift -verify
5+
// RUN: %target-swift-frontend -typecheck -plugin-path %swift-plugin-dir -o %t/test.swiftmodule -I %t -import-objc-header %t/bridging.h -enable-experimental-feature SafeInteropWrappers -strict-memory-safety -warnings-as-errors -Xcc -Werror -Xcc -Wno-nullability-completeness -Xcc -Wno-div-by-zero -Xcc -Wno-pointer-to-int-cast %t/test.swift -dump-macro-expansions 2>&1 | %FileCheck --dry-run > %t/macro-expansions.out
6+
// RUN: %diff %t/macro-expansions.out %t/macro-expansions.expected
7+
// RUN: %target-swift-frontend -typecheck -plugin-path %swift-plugin-dir -o %t/test.swiftmodule -I %t -import-objc-header %t/bridging.h -enable-experimental-feature SafeInteropWrappers -strict-memory-safety -warnings-as-errors -Xcc -Werror -Xcc -Wno-nullability-completeness -Xcc -Wno-div-by-zero -Xcc -Wno-pointer-to-int-cast %t/test.swift -dump-source-file-imports 2>&1 | %FileCheck --dry-run > %t/imports.out
8+
// RUN: %diff %t/imports.out %t/imports.expected
9+
10+
//--- imports.expected
11+
imports for TMP_DIR/test.swift:
12+
Swift
13+
__ObjC
14+
_StringProcessing
15+
_SwiftConcurrencyShims
16+
_Concurrency
17+
imports for __ObjC.foo:
18+
imports for @__swiftmacro_So3foo15_SwiftifyImportfMp_.swift:
19+
__ObjC
20+
Swift
21+
22+
//--- macro-expansions.expected
23+
@__swiftmacro_So3foo15_SwiftifyImportfMp_.swift
24+
------------------------------
25+
/// This is an auto-generated wrapper for safer interop
26+
@_alwaysEmitIntoClient @available(visionOS 1.0, tvOS 12.2, watchOS 5.2, iOS 12.2, macOS 10.14.4, *) @_disfavoredOverload public func foo(_ p: Span<Int32>) {
27+
let len = Int32(exactly: p.count)!
28+
return unsafe p.withUnsafeBufferPointer { _pPtr in
29+
return unsafe foo(len, _pPtr.baseAddress!)
30+
}
31+
}
32+
------------------------------
33+
34+
//--- test.swift
35+
func test(s: Span<CInt>) {
36+
foo(s)
37+
}
38+
39+
//--- bridging.h
40+
#include <ptrcheck.h>
41+
#include <lifetimebound.h>
42+
43+
void foo(int len, const int * __counted_by(len) p __noescape);

0 commit comments

Comments
 (0)