Skip to content

Commit a0efe4f

Browse files
committed
Merge pull request #2371 from jckarter/map-int-to-nsinteger
IRGen: Map Int and UInt to Clang types via NS[U]Integer.
2 parents eadc7fd + 08f9f11 commit a0efe4f

File tree

3 files changed

+78
-0
lines changed

3 files changed

+78
-0
lines changed

lib/IRGen/GenClangType.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,30 @@ clang::CanQualType GenClangType::visitStructType(CanStructType type) {
225225
return Converter.reverseBuiltinTypeMapping(IGM, type);
226226
}
227227

228+
static clang::CanQualType getClangBuiltinTypeFromTypedef(
229+
const clang::ASTContext &context, StringRef typedefName) {
230+
auto identifier = &context.Idents.get(typedefName);
231+
auto lookup = context.getTranslationUnitDecl()->lookup(identifier);
232+
233+
clang::TypedefDecl *typedefDecl = nullptr;
234+
for (auto found : lookup) {
235+
auto foundTypedef = dyn_cast<clang::TypedefDecl>(found);
236+
if (!foundTypedef)
237+
continue;
238+
typedefDecl = foundTypedef;
239+
break;
240+
}
241+
if (!typedefDecl)
242+
return {};
243+
244+
auto underlyingTy =
245+
context.getCanonicalType(typedefDecl->getUnderlyingType());
246+
247+
if (underlyingTy->getAs<clang::BuiltinType>())
248+
return underlyingTy;
249+
return {};
250+
}
251+
228252
clang::CanQualType
229253
ClangTypeConverter::reverseBuiltinTypeMapping(IRGenModule &IGM,
230254
CanStructType type) {
@@ -260,6 +284,22 @@ ClangTypeConverter::reverseBuiltinTypeMapping(IRGenModule &IGM,
260284
clang::BuiltinType::Kind builtinKind) {
261285
CanType swiftType = getNamedSwiftType(stdlib, swiftName);
262286
if (!swiftType) return;
287+
288+
// Handle Int and UInt specially. On Apple platforms, these correspond to
289+
// the NSInteger and NSUInteger typedefs, so map them back to those typedefs
290+
// if they're available, to ensure we get consistent ObjC @encode strings.
291+
if (swiftType->getAnyNominal() == IGM.Context.getIntDecl()) {
292+
if (auto NSIntegerTy = getClangBuiltinTypeFromTypedef(ctx, "NSInteger")) {
293+
Cache.insert({swiftType, NSIntegerTy});
294+
return;
295+
}
296+
} else if (swiftType->getAnyNominal() == IGM.Context.getUIntDecl()) {
297+
if (auto NSUIntegerTy =
298+
getClangBuiltinTypeFromTypedef(ctx, "NSUInteger")) {
299+
Cache.insert({swiftType, NSUIntegerTy});
300+
return;
301+
}
302+
}
263303

264304
Cache.insert({swiftType, getClangBuiltinTypeFromKind(ctx, builtinKind)});
265305
};

test/IRGen/objc_int_encoding.sil

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) %s -emit-ir | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize
2+
// REQUIRES: objc_interop
3+
4+
// CHECK: [[SELECTOR:@.*]] = private global {{.*}} c"fooWithX:\00"
5+
6+
// CHECK-64: [[INT_UINT_METHOD_ENCODING:@.*]] = private unnamed_addr constant {{.*}} c"Q24@0:8q16\00"
7+
// CHECK-32: [[INT_UINT_METHOD_ENCODING:@.*]] = private unnamed_addr constant {{.*}} c"I12@0:4i8\00"
8+
9+
// CHECK: @_INSTANCE_METHODS__TtC17objc_int_encoding3Foo = private constant {{.*}} [[SELECTOR]], {{.*}} [[INT_UINT_METHOD_ENCODING]], {{.*}} @_TToFC17objc_int_encoding3Foo3foofT1xSi_Su
10+
11+
sil_stage canonical
12+
13+
import Builtin
14+
import Swift
15+
import Foundation
16+
17+
class Foo: NSObject {
18+
@objc override init() {}
19+
20+
@objc func foo(x: Int) -> UInt
21+
}
22+
23+
sil hidden @_TToFC17objc_int_encoding3Foo3foofT1xSi_Su : $@convention(objc_method) (Int, @guaranteed Foo) -> UInt {
24+
entry(%0 : $Int, %1 : $Foo):
25+
unreachable
26+
}
27+
sil @_TToFC17objc_int_encoding3FoocfT_S0_ : $@convention(objc_method) (@owned Foo) -> @owned Foo {
28+
entry(%1 : $Foo):
29+
unreachable
30+
}
31+
32+
sil_vtable Foo {}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,14 @@
44
#define OBJC_ARC_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode")))
55
#define NS_AUTOMATED_REFCOUNT_UNAVAILABLE OBJC_ARC_UNAVAILABLE
66

7+
#ifdef __LP64__
78
typedef unsigned long NSUInteger;
89
typedef long NSInteger;
10+
#else
11+
typedef unsigned int NSUInteger;
12+
typedef int NSInteger;
13+
#endif
14+
915
typedef __typeof__(__objc_yes) BOOL;
1016

1117
typedef struct objc_selector *SEL;

0 commit comments

Comments
 (0)