Skip to content

Commit e6b830b

Browse files
committed
[cxx-interop] Import CF_OPTIONS types such as Foundation.NSTextCheckingType correctly
This fixes linker errors which occurred when using Foundation extensions to `Swift.String`, such as `func replacingOccurrences`. After the last rebranch, Clang started wrapping certain types in `clang::ElaboratedType`. This caused CF_OPTIONS types such as `Foundation.NSTextCheckingType` to be imported incorrectly in C++ language mode (`NSTextCheckingType` was imported as `uint64_t` without getting the special treatment of a CF type), which was causing deserialization errors when Swift tried reading `Foundation.swiftmodule`. Those deserialization errors were silenced by default. The IR for those functions was not emitted, which caused linker errors later. rdar://109830032
1 parent 21a2b78 commit e6b830b

File tree

5 files changed

+36
-0
lines changed

5 files changed

+36
-0
lines changed

Diff for: lib/ClangImporter/CFTypeInfo.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ CFPointeeInfo
5353
CFPointeeInfo::classifyTypedef(const clang::TypedefNameDecl *typedefDecl) {
5454
clang::QualType type = typedefDecl->getUnderlyingType();
5555

56+
if (auto elaborated = type->getAs<clang::ElaboratedType>())
57+
type = elaborated->desugar();
58+
5659
if (auto subTypedef = type->getAs<clang::TypedefType>()) {
5760
if (classifyTypedef(subTypedef->getDecl()))
5861
return forTypedef(subTypedef->getDecl());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#define __CF_OPTIONS_ATTRIBUTES __attribute__((flag_enum,enum_extensibility(open)))
2+
#if (__cplusplus)
3+
#define CF_OPTIONS(_type, _name) __attribute__((availability(swift,unavailable))) _type _name; enum __CF_OPTIONS_ATTRIBUTES : _name
4+
#else
5+
#define CF_OPTIONS(_type, _name) enum __CF_OPTIONS_ATTRIBUTES _name : _type _name; enum _name : _type
6+
#endif
7+
8+
typedef CF_OPTIONS(unsigned int, NSTextCheckingType) {
9+
NSTextCheckingTypeOrthography = 1ULL << 0,
10+
NSTextCheckingTypeSpelling = 1ULL << 1,
11+
// ...
12+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import NSTextCheckingResult
2+
3+
public func foo() -> NSTextCheckingType {
4+
return .orthography
5+
}

Diff for: test/Interop/Cxx/objc-correctness/Inputs/module.modulemap

+5
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,8 @@ module OSObject {
2424
requires objc
2525
requires cplusplus
2626
}
27+
28+
module NSTextCheckingResult {
29+
header "NSTextCheckingResult.h"
30+
requires objc
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend %S/Inputs/SwiftTextCheckingResult.swift -I %S/Inputs -module-name SwiftTextCheckingResult -enable-objc-interop -emit-module -emit-module-path %t/SwiftTextCheckingResult.swiftmodule
3+
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %t -I %S/Inputs -module-name SwiftTest -enable-objc-interop -enable-experimental-cxx-interop
4+
5+
// REQUIRES: objc_interop
6+
7+
import SwiftTextCheckingResult
8+
9+
let _ = foo()
10+
11+
// CHECK: @"$sSy10FoundationE20replacingOccurrences2of4with7options5rangeSSqd___qd_0_So22NSStringCompareOptionsVSnySS5IndexVGSgtSyRd__SyRd_0_r0_lF"

0 commit comments

Comments
 (0)