Skip to content

Commit 299d109

Browse files
authored
Merge pull request #59042 from plotfi/enum-cxx-interop-options-struct
[C++-Interop] Fix EffectiveClangContext for NS_OPTIONS EnumDecl lookup.
2 parents 7eb3657 + dd4cdfb commit 299d109

File tree

4 files changed

+59
-0
lines changed

4 files changed

+59
-0
lines changed

lib/ClangImporter/SwiftLookupTable.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/Basic/LLVM.h"
2222
#include "swift/AST/Identifier.h"
2323
#include "clang/AST/Decl.h"
24+
#include "clang/AST/DeclCXX.h"
2425
#include "clang/AST/DeclObjC.h"
2526
#include "clang/Serialization/ASTBitCodes.h"
2627
#include "clang/Serialization/ModuleFileExtension.h"
@@ -197,6 +198,8 @@ class EffectiveClangContext {
197198
DC = omDecl->getCanonicalDecl();
198199
} else if (auto fDecl = dyn_cast<clang::FunctionDecl>(dc)) {
199200
DC = fDecl->getCanonicalDecl();
201+
} else if (auto externCDecl = dyn_cast<clang::LinkageSpecDecl>(dc)) {
202+
DC = externCDecl->getLexicalDeclContext();
200203
} else {
201204
assert(isa<clang::TranslationUnitDecl>(dc) ||
202205
isa<clang::LinkageSpecDecl>(dc) ||
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Enum usage that is bitwise-able and assignable in C++, aka how CF_OPTIONS
2+
// does things.
3+
4+
#if __has_attribute(enum_extensibility)
5+
#define __CF_ENUM_ATTRIBUTES __attribute__((enum_extensibility(open)))
6+
#define __CF_CLOSED_ENUM_ATTRIBUTES __attribute__((enum_extensibility(closed)))
7+
#define __CF_OPTIONS_ATTRIBUTES __attribute__((flag_enum,enum_extensibility(open)))
8+
#else
9+
#define __CF_ENUM_ATTRIBUTES
10+
#define __CF_CLOSED_ENUM_ATTRIBUTES
11+
#define __CF_OPTIONS_ATTRIBUTES
12+
#endif
13+
14+
// explicitly use extern "C" rather than setting it in the modulemap file as
15+
// would be the case with Foundation's modulemap.
16+
extern "C" {
17+
18+
#define CF_OPTIONS(_type, _name) _type __attribute__((availability(swift, unavailable))) _name; enum __CF_OPTIONS_ATTRIBUTES : _name
19+
#define NS_OPTIONS(_type, _name) CF_OPTIONS(_type, _name)
20+
21+
typedef unsigned long NSUInteger;
22+
23+
typedef NS_OPTIONS(NSUInteger, NSBinarySearchingOptions) {
24+
NSBinarySearchingFirstEqual = (1UL << 8),
25+
NSBinarySearchingLastEqual = (1UL << 9),
26+
NSBinarySearchingInsertionIndex = (1UL << 10),
27+
};
28+
29+
}

test/Interop/Cxx/enum/Inputs/module.modulemap

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,8 @@ module CenumsWithOptionsOmit {
1717
header "c-enums-withOptions-omit.h"
1818
requires cplusplus
1919
}
20+
21+
module CenumsNSOptions {
22+
header "c-enums-NS_OPTIONS.h"
23+
requires cplusplus
24+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %target-swift-ide-test -print-module -module-to-print=CenumsNSOptions -I %S/Inputs -source-filename=x -enable-experimental-cxx-interop | %FileCheck %s
2+
// REQUIRES: objc_interop
3+
4+
import CenumsNSOptions
5+
6+
// CHECK: typealias NSBinarySearchingOptions = UInt
7+
// CHECK-NEXT: struct NSBinarySearchingOptions : OptionSet, @unchecked Sendable {
8+
// CHECK-NEXT: init(rawValue: UInt)
9+
// CHECK-NEXT: let rawValue: UInt
10+
// CHECK-NEXT: typealias RawValue = UInt
11+
// CHECK-NEXT: typealias Element = NSBinarySearchingOptions
12+
// CHECK-NEXT: typealias ArrayLiteralElement = NSBinarySearchingOptions
13+
// CHECK-NEXT: static var firstEqual: NSBinarySearchingOptions { get }
14+
// CHECK-NEXT: @available(swift, obsoleted: 3, renamed: "firstEqual")
15+
// CHECK-NEXT: static var FirstEqual: NSBinarySearchingOptions { get }
16+
// CHECK-NEXT: static var lastEqual: NSBinarySearchingOptions { get }
17+
// CHECK-NEXT: @available(swift, obsoleted: 3, renamed: "lastEqual")
18+
// CHECK-NEXT: static var LastEqual: NSBinarySearchingOptions { get }
19+
// CHECK-NEXT: static var insertionIndex: NSBinarySearchingOptions { get }
20+
// CHECK-NEXT: @available(swift, obsoleted: 3, renamed: "insertionIndex")
21+
// CHECK-NEXT: static var InsertionIndex: NSBinarySearchingOptions { get }
22+
// CHECK-NEXT: }

0 commit comments

Comments
 (0)