Skip to content

Commit 197dc4b

Browse files
authored
Merge pull request #66696 from plotfi/plotfi-cxx-interop-uicontrolstate-mangling-5.9
[cxx-interop] Add fix for corner case where NS_OPTIONS typedef has to be desugared
2 parents 1dcd4c0 + 83bdd59 commit 197dc4b

File tree

5 files changed

+58
-6
lines changed

5 files changed

+58
-6
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6877,14 +6877,25 @@ const clang::TypedefType *ClangImporter::getTypeDefForCXXCFOptionsDefinition(
68776877
if (!enumDecl->getDeclName().isEmpty())
68786878
return nullptr;
68796879

6880-
if (auto typedefType = dyn_cast<clang::TypedefType>(
6881-
enumDecl->getIntegerType().getTypePtr())) {
6882-
if (auto enumExtensibilityAttr =
6883-
typedefType->getDecl()->getAttr<clang::EnumExtensibilityAttr>();
6884-
enumExtensibilityAttr &&
6880+
const clang::ElaboratedType *elaboratedType =
6881+
dyn_cast<clang::ElaboratedType>(enumDecl->getIntegerType().getTypePtr());
6882+
if (auto typedefType =
6883+
elaboratedType
6884+
? dyn_cast<clang::TypedefType>(elaboratedType->desugar())
6885+
: dyn_cast<clang::TypedefType>(
6886+
enumDecl->getIntegerType().getTypePtr())) {
6887+
auto enumExtensibilityAttr =
6888+
elaboratedType
6889+
? enumDecl->getAttr<clang::EnumExtensibilityAttr>()
6890+
: typedefType->getDecl()->getAttr<clang::EnumExtensibilityAttr>();
6891+
const bool hasFlagEnumAttr =
6892+
elaboratedType ? enumDecl->hasAttr<clang::FlagEnumAttr>()
6893+
: typedefType->getDecl()->hasAttr<clang::FlagEnumAttr>();
6894+
6895+
if (enumExtensibilityAttr &&
68856896
enumExtensibilityAttr->getExtensibility() ==
68866897
clang::EnumExtensibilityAttr::Open &&
6887-
typedefType->getDecl()->hasAttr<clang::FlagEnumAttr>()) {
6898+
hasFlagEnumAttr) {
68886899
return Impl.isUnavailableInSwift(typedefType->getDecl()) ? typedefType
68896900
: nullptr;
68906901
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
Name: NSOptionsMangling
3+
Tags:
4+
- Name: UIControlState
5+
SwiftName: UIControl.State
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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, UIControlState) { UIControlStateNormal = 0 };
9+
10+
#ifdef __cplusplus
11+
#define UIKIT_EXTERN extern "C" __attribute__((visibility ("default")))
12+
#else
13+
#define UIKIT_EXTERN extern __attribute__((visibility ("default")))
14+
#endif
15+
16+
@interface UIView
17+
@end
18+
19+
UIKIT_EXTERN
20+
@interface UIControl : UIView
21+
@end
22+

test/Interop/Cxx/objc-correctness/Inputs/module.modulemap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,6 @@ module CxxClassWithNSStringInit [extern_c] {
99
requires cplusplus
1010
}
1111

12+
module NSOptionsMangling {
13+
header "NSOptionsMangling.h"
14+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %target-swift-frontend -I %S/Inputs -c -cxx-interoperability-mode=swift-5.9 %s -S -o - | %FileCheck %s
2+
// RUN: %target-swift-frontend -I %S/Inputs -c %s -S -o - | %FileCheck %s
3+
4+
// REQUIRES: objc_interop
5+
6+
// CHECK: _$sSo14UIControlStateV4main7FooableACMc
7+
// The following check is to ensure the conformance is mangled properly:
8+
// protocol conformance descriptor for __C.UIControlState : main.Fooable in main
9+
import NSOptionsMangling
10+
protocol Fooable { }
11+
extension UIControl.State: Fooable {}

0 commit comments

Comments
 (0)