Skip to content

Commit a8da101

Browse files
authored
Merge pull request #16239 from DougGregor/import-bridged-typedef-4.2
[4.2] [Clang importer] Honor swift_bridged_typedef attribute.
2 parents 4a4c068 + d6fc939 commit a8da101

File tree

6 files changed

+50
-13
lines changed

6 files changed

+50
-13
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2529,7 +2529,7 @@ namespace {
25292529
clang::QualType ClangType = Decl->getUnderlyingType();
25302530
SwiftType = Impl.importTypeIgnoreIUO(
25312531
ClangType, ImportTypeKind::Typedef, isInSystemModule(DC),
2532-
getTypedefBridgeability(ClangType), OTK_Optional);
2532+
getTypedefBridgeability(Decl, ClangType), OTK_Optional);
25332533
}
25342534

25352535
if (!SwiftType)

lib/ClangImporter/ImportType.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -663,12 +663,11 @@ namespace {
663663
auto underlyingType = type->desugar();
664664

665665
// Figure out the bridgeability we would normally use for this typedef.
666-
auto typedefBridgeability = getTypedefBridgeability(underlyingType);
666+
auto typedefBridgeability =
667+
getTypedefBridgeability(type->getDecl(), underlyingType);
667668

668669
// Figure out the typedef we should actually use.
669-
auto underlyingBridgeability =
670-
(Bridging == Bridgeability::Full
671-
? typedefBridgeability : Bridgeability::None);
670+
auto underlyingBridgeability = Bridging;
672671
SwiftTypeConverter innerConverter(Impl, AllowNSUIntegerAsInt,
673672
underlyingBridgeability);
674673
auto underlyingResult = innerConverter.Visit(underlyingType);
@@ -685,7 +684,8 @@ namespace {
685684
#ifndef NDEBUG
686685
switch (underlyingResult.Hint) {
687686
case ImportHint::Block:
688-
// Blocks change in all sorts of ways, due to bridging.
687+
case ImportHint::ObjCBridged:
688+
// Bridging is fine for Objective-C and blocks.
689689
break;
690690
case ImportHint::NSUInteger:
691691
// NSUInteger might be imported as Int rather than UInt depending
@@ -1088,7 +1088,6 @@ namespace {
10881088
static bool canBridgeTypes(ImportTypeKind importKind) {
10891089
switch (importKind) {
10901090
case ImportTypeKind::Abstract:
1091-
case ImportTypeKind::Typedef:
10921091
case ImportTypeKind::Value:
10931092
case ImportTypeKind::Variable:
10941093
case ImportTypeKind::AuditedVariable:
@@ -1104,6 +1103,7 @@ static bool canBridgeTypes(ImportTypeKind importKind) {
11041103
case ImportTypeKind::Property:
11051104
case ImportTypeKind::PropertyWithReferenceSemantics:
11061105
case ImportTypeKind::BridgedValue:
1106+
case ImportTypeKind::Typedef:
11071107
return true;
11081108
}
11091109

@@ -1286,7 +1286,7 @@ static ImportedType adjustTypeForConcreteImport(
12861286
// In a bridgeable context, or in the direct structure of a typedef,
12871287
// we would prefer to instead use the default Swift convention.
12881288
if (hint == ImportHint::Block) {
1289-
if (canBridgeTypes(importKind) || importKind == ImportTypeKind::Typedef) {
1289+
if (canBridgeTypes(importKind)) {
12901290
auto fTy = importedType->castTo<FunctionType>();
12911291
FunctionType::ExtInfo einfo = fTy->getExtInfo();
12921292
if (einfo.getRepresentation() != FunctionTypeRepresentation::Swift) {
@@ -1330,13 +1330,18 @@ static ImportedType adjustTypeForConcreteImport(
13301330
// bridge, do so.
13311331
if (hint == ImportHint::ObjCBridged &&
13321332
canBridgeTypes(importKind) &&
1333-
importKind != ImportTypeKind::PropertyWithReferenceSemantics) {
1333+
importKind != ImportTypeKind::PropertyWithReferenceSemantics &&
1334+
!(importKind == ImportTypeKind::Typedef &&
1335+
bridging == Bridgeability::None)) {
13341336
// id and Any can be bridged without Foundation. There would be
13351337
// bootstrapping issues with the ObjectiveC module otherwise.
13361338
if (hint.BridgedType->isAny()
13371339
|| impl.tryLoadFoundationModule()
13381340
|| impl.ImportForwardDeclarations) {
1339-
importedType = hint.BridgedType;
1341+
1342+
// Set the bridged type if it wasn't done already.
1343+
if (!importedType->isEqual(hint.BridgedType))
1344+
importedType = hint.BridgedType;
13401345
}
13411346
}
13421347

@@ -2484,7 +2489,7 @@ Type ClangImporter::Implementation::getSugaredTypeReference(TypeDecl *type) {
24842489
}
24852490

24862491
return NameAliasType::get(typealias, parentType, SubstitutionMap(),
2487-
typealias->getUnderlyingTypeLoc().getType());
2492+
typealias->getUnderlyingTypeLoc().getType());
24882493
}
24892494

24902495
return type->getDeclaredInterfaceType();

lib/ClangImporter/ImporterImpl.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,14 @@ enum class Bridgeability {
196196
///
197197
/// In either case we end up losing sugar at some uses sites, so this is more
198198
/// about what the right default is.
199-
static inline Bridgeability getTypedefBridgeability(clang::QualType type) {
200-
return type->isBlockPointerType() ? Bridgeability::Full : Bridgeability::None;
199+
static inline Bridgeability getTypedefBridgeability(
200+
const clang::TypedefNameDecl *decl,
201+
clang::QualType type) {
202+
return decl->hasAttr<clang::SwiftBridgedTypedefAttr>()
203+
? Bridgeability::Full
204+
: type->isBlockPointerType()
205+
? Bridgeability::Full
206+
: Bridgeability::None;
201207
}
202208

203209
/// \brief Describes the kind of the C type that can be mapped to a stdlib

test/IDE/print_clang_decls.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
// RUN: %target-swift-ide-test(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -print-module -source-filename %s -module-to-print=nullability -function-definitions=false -prefer-type-repr=true > %t.printed.txt
2323
// RUN: %FileCheck %s -check-prefix=CHECK-NULLABILITY -strict-whitespace < %t.printed.txt
2424

25+
// RUN: %target-swift-ide-test(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -print-module -source-filename %s -module-to-print=bridged_typedef -function-definitions=false -prefer-type-repr=true > %t.printed.txt
26+
// RUN: %FileCheck %s -check-prefix=CHECK-BRIDGED-TYPEDEF -strict-whitespace < %t.printed.txt
27+
2528
// TAG_DECLS_AND_TYPEDEFS: {{^}}struct FooStruct1 {{{$}}
2629
// TAG_DECLS_AND_TYPEDEFS: {{^}} var x: Int32{{$}}
2730
// TAG_DECLS_AND_TYPEDEFS: {{^}} var y: Double{{$}}
@@ -153,3 +156,8 @@
153156
// CHECK-NULLABILITY: func optArrayMethod() -> [Any]?
154157
// CHECK-NULLABILITY: }
155158
// CHECK-NULLABILITY: func compare_classes(_ sc1: SomeClass, _ sc2: SomeClass, _ sc3: SomeClass!)
159+
160+
// CHECK-BRIDGED-TYPEDEF: typealias NSMyAmazingStringAlias = String
161+
// CHECK-BRIDGED-TYPEDEF: func acceptNSMyAmazingStringAlias(_ param: NSMyAmazingStringAlias?)
162+
// CHECK-BRIDGED-TYPEDEF: func acceptNSMyAmazingStringAliasArray(_ param: [NSMyAmazingStringAlias])
163+
// CHECK-BRIDGED-TYPEDEF: func acceptIndirectedAmazingAlias(_ param: AutoreleasingUnsafeMutablePointer<NSString>?)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#ifndef BRIDGED_TYPEDEF_H
2+
#define BRIDGED_TYPEDEF_H
3+
4+
@import Foundation;
5+
6+
7+
typedef NSString *NSMyAmazingStringAlias __attribute__((swift_bridged_typedef));
8+
9+
void acceptNSMyAmazingStringAlias(NSMyAmazingStringAlias _Nullable param);
10+
void acceptNSMyAmazingStringAliasArray(NSArray<NSMyAmazingStringAlias> * _Nonnull param);
11+
void acceptIndirectedAmazingAlias(NSMyAmazingStringAlias _Nonnull * _Nullable param);
12+
13+
#endif

test/Inputs/clang-importer-sdk/usr/include/module.map

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,8 @@ module OtherSubscripts {
126126
header "OtherSubscripts.h"
127127
export *
128128
}
129+
130+
module bridged_typedef {
131+
header "bridged_typedef.h"
132+
export *
133+
}

0 commit comments

Comments
 (0)