Skip to content

Commit 0bd4a0a

Browse files
authored
[PrintAsObjC] Handle typealiases in ObjC generics. (#4321)
More specifically, don't try to emit a definition for them. Just fall through to what we do for forward-declarations...which also needed some fixing, to make sure we don't use a Swift typealias as its underlying type but never import the underlying type. https://bugs.swift.org/browse/SR-2352
2 parents e6c313b + ea4d110 commit 0bd4a0a

File tree

6 files changed

+56
-8
lines changed

6 files changed

+56
-8
lines changed

lib/PrintAsObjC/PrintAsObjC.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1841,7 +1841,8 @@ class ModuleWriter {
18411841
if (TD == container)
18421842
return;
18431843

1844-
if (finder.isWithinConstrainedObjCGeneric()) {
1844+
if (finder.isWithinConstrainedObjCGeneric() &&
1845+
isa<NominalTypeDecl>(TD)) {
18451846
// We can delay individual members of classes; do so if necessary.
18461847
if (isa<ClassDecl>(container)) {
18471848
if (!tryRequire(TD)) {
@@ -1876,18 +1877,21 @@ class ModuleWriter {
18761877
if (!forwardDeclare(CD)) {
18771878
(void)addImport(CD);
18781879
}
1879-
} else if (auto PD = dyn_cast<ProtocolDecl>(TD))
1880+
} else if (auto PD = dyn_cast<ProtocolDecl>(TD)) {
18801881
forwardDeclare(PD);
1881-
else if (addImport(TD))
1882+
} else if (auto TAD = dyn_cast<TypeAliasDecl>(TD)) {
1883+
(void)addImport(TD);
1884+
// Just in case, make sure the underlying type is visible too.
1885+
finder.visit(TAD->getUnderlyingType());
1886+
} else if (addImport(TD)) {
18821887
return;
1883-
else if (auto ED = dyn_cast<EnumDecl>(TD))
1888+
} else if (auto ED = dyn_cast<EnumDecl>(TD)) {
18841889
forwardDeclare(ED);
1885-
else if (auto TAD = dyn_cast<TypeAliasDecl>(TD))
1886-
finder.visit(TAD->getUnderlyingType());
1887-
else if (isa<AbstractTypeParamDecl>(TD))
1890+
} else if (isa<AbstractTypeParamDecl>(TD)) {
18881891
llvm_unreachable("should not see type params here");
1889-
else
1892+
} else {
18901893
assert(false && "unknown local type decl");
1894+
}
18911895
});
18921896

18931897
if (needsToBeIndividuallyDelayed) {

test/Inputs/clang-importer-sdk/usr/include/objc_generics.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,5 @@ void takeGenericClass(__nullable GenericClass<NSString *> *thing);
8686
- (void)doThing:(__nonnull T<Pettable>)thing;
8787
@end
8888

89+
typedef id <Fungible> FungibleObject;
90+

test/PrintAsObjC/Inputs/custom-modules/module.map

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,7 @@ module OverrideBase [system] {
2323
header "override.h"
2424
export *
2525
}
26+
27+
module OtherModule {
28+
// Deliberately empty. Used by depends-on-swift-framework.swift.
29+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import objc_generics
2+
3+
public typealias AliasForFungible = Fungible

test/PrintAsObjC/classes.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,10 @@ public class NonObjCClass { }
711711
@objc func takeAndReturnGenericClass(_ x: GenericClass<NSString>?) -> GenericClass<AnyObject> { fatalError("") }
712712
// CHECK: - (FungibleContainer<id <Fungible>> * _Null_unspecified)takeAndReturnFungibleContainer:(FungibleContainer<Spoon *> * _Nonnull)x;
713713
@objc func takeAndReturnFungibleContainer(_ x: FungibleContainer<Spoon>) -> FungibleContainer<Fungible>! { fatalError("") }
714+
715+
typealias Dipper = Spoon
716+
// CHECK: - (FungibleContainer<FungibleObject> * _Nonnull)fungibleContainerWithAliases:(FungibleContainer<Spoon *> * _Nullable)x;
717+
@objc func fungibleContainerWithAliases(_ x: FungibleContainer<Dipper>?) -> FungibleContainer<FungibleObject> { fatalError("") }
714718
}
715719
// CHECK: @end
716720

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: rm -rf %t && mkdir %t
2+
3+
// FIXME: BEGIN -enable-source-import hackaround
4+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift
5+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift
6+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/Foundation.swift
7+
// FIXME: END -enable-source-import hackaround
8+
9+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t %S/Inputs/depends-on-swift-framework-helper.swift -module-name OtherModule
10+
11+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -import-objc-header %S/../Inputs/empty.h -emit-module -o %t %s -module-name main
12+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -import-objc-header %S/../Inputs/empty.h -parse-as-library %t/main.swiftmodule -parse -emit-objc-header-path %t/main.h
13+
14+
// RUN: %FileCheck %s < %t/main.h
15+
16+
// RUN: %check-in-clang -I %S/Inputs/custom-modules %t/main.h
17+
// RUN: %check-in-clang -fno-modules -Qunused-arguments %t/main.h -include objc_generics.h
18+
19+
// REQUIRES: objc_interop
20+
21+
import Foundation
22+
import objc_generics
23+
import OtherModule
24+
25+
// CHECK-LABEL: @interface Test
26+
public class Test: NSObject {
27+
// CHECK: - (void)testSimpleTypealias:(id <Fungible> _Nonnull)_;
28+
func testSimpleTypealias(_: AliasForFungible) {}
29+
// CHECK: - (void)testGenericTypealias:(FungibleContainer<id <Fungible>> * _Nonnull)_;
30+
func testGenericTypealias(_: FungibleContainer<AliasForFungible>) {}
31+
} // CHECK: @end

0 commit comments

Comments
 (0)