Skip to content

Fix effective context construction for NS_OPTIONS in linkage spec #62236

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions lib/ClangImporter/SwiftLookupTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,12 @@ class EffectiveClangContext {
EffectiveClangContext(const clang::DeclContext *dc)
: KindOrBiasedLength(DeclContext) {
assert(dc != nullptr && "use null constructor instead");

// Skip over any linkage spec decl contexts
while (auto externCDecl = dyn_cast<clang::LinkageSpecDecl>(dc)) {
dc = externCDecl->getLexicalDeclContext();
}

if (auto tagDecl = dyn_cast<clang::TagDecl>(dc)) {
DC = tagDecl->getCanonicalDecl();
} else if (auto oiDecl = dyn_cast<clang::ObjCInterfaceDecl>(dc)) {
Expand All @@ -198,11 +204,8 @@ class EffectiveClangContext {
DC = omDecl->getCanonicalDecl();
} else if (auto fDecl = dyn_cast<clang::FunctionDecl>(dc)) {
DC = fDecl->getCanonicalDecl();
} else if (auto externCDecl = dyn_cast<clang::LinkageSpecDecl>(dc)) {
DC = externCDecl->getLexicalDeclContext();
} else {
assert(isa<clang::TranslationUnitDecl>(dc) ||
isa<clang::LinkageSpecDecl>(dc) ||
isa<clang::NamespaceDecl>(dc) ||
isa<clang::ObjCContainerDecl>(dc) &&
"No other kinds of effective Clang contexts");
Expand Down Expand Up @@ -526,7 +529,7 @@ class SwiftLookupTable {

/// Retrieve the set of base names that are stored in the globals-as-members lookup table.
SmallVector<SerializedSwiftName, 4> allGlobalsAsMembersBaseNames();

/// Lookup Objective-C members with the given base name, regardless
/// of context.
SmallVector<clang::NamedDecl *, 4>
Expand Down
8 changes: 8 additions & 0 deletions test/Interop/Cxx/enum/Inputs/CenumsNSOptions.apinotes
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,11 @@ Enumerators:
SwiftName: SwiftOptionThreeApiNotes
- Name: API_NOTES_NAMED_OptionFour
SwiftName: SwiftOptionFourApiNotes
Tags:
- Name: UIPrinterJobTypes
SwiftName: UIPrinter.JobTypes
SwiftVersions:
- Version: 4
Tags:
- Name: UIPrinterJobTypes
SwiftName: UIPrinterJobTypes
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Name: CenumsNSOptionsExternC
Tags:
- Name: UIPrinterJobTypes
SwiftName: UIPrinter.JobTypes
SwiftVersions:
- Version: 4
Tags:
- Name: UIPrinterJobTypes
SwiftName: UIPrinterJobTypes
19 changes: 19 additions & 0 deletions test/Interop/Cxx/enum/Inputs/c-enums-NS_OPTIONS.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ extern "C" {
#define CF_OPTIONS(_type, _name) _type __attribute__((availability(swift, unavailable))) _name; enum __CF_OPTIONS_ATTRIBUTES : _name
#define NS_OPTIONS(_type, _name) CF_OPTIONS(_type, _name)
#define NS_REFINED_FOR_SWIFT __attribute__((swift_private))
#define UIKIT_EXTERN extern "C" __attribute__((visibility("default")))

typedef unsigned long NSUInteger;
typedef long NSInteger;

typedef NS_OPTIONS(NSUInteger, NSBinarySearchingOptions) {
NSBinarySearchingFirstEqual = (1UL << 8),
Expand All @@ -39,6 +41,23 @@ typedef NS_OPTIONS(NSUInteger, NSAttributedStringFormattingOptions) {
- (instancetype)initWithOptions:(NSAttributedStringFormattingOptions)options
NS_REFINED_FOR_SWIFT;
@end

UIKIT_EXTERN
@interface UIPrinter

typedef NS_OPTIONS(NSInteger, UIPrinterJobTypes) {
UIPrinterJobTypeUnknown = 0,
UIPrinterJobTypeDocument = 1 << 0,
UIPrinterJobTypeEnvelope = 1 << 1,
UIPrinterJobTypeLabel = 1 << 2,
UIPrinterJobTypePhoto = 1 << 3,
UIPrinterJobTypeReceipt = 1 << 4,
UIPrinterJobTypeRoll = 1 << 5,
UIPrinterJobTypeLargeFormat = 1 << 6,
UIPrinterJobTypePostcard = 1 << 7
};

@end
}

typedef NS_OPTIONS(NSUInteger, Foo) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#if __has_attribute(enum_extensibility)
#define __CF_ENUM_ATTRIBUTES __attribute__((enum_extensibility(open)))
#define __CF_CLOSED_ENUM_ATTRIBUTES __attribute__((enum_extensibility(closed)))
#define __CF_OPTIONS_ATTRIBUTES __attribute__((flag_enum,enum_extensibility(open)))
#else
#define __CF_ENUM_ATTRIBUTES
#define __CF_CLOSED_ENUM_ATTRIBUTES
#define __CF_OPTIONS_ATTRIBUTES
#endif

#define CF_OPTIONS(_type, _name) _type __attribute__((availability(swift, unavailable))) _name; enum __CF_OPTIONS_ATTRIBUTES : _name
#define NS_OPTIONS(_type, _name) CF_OPTIONS(_type, _name)
#define UIKIT_EXTERN extern "C" __attribute__((visibility("default")))

typedef long NSInteger;

UIKIT_EXTERN
@interface UIPrinter

typedef NS_OPTIONS(NSInteger, UIPrinterJobTypes) {
UIPrinterJobTypeUnknown = 0,
UIPrinterJobTypeDocument = 1 << 0,
UIPrinterJobTypeEnvelope = 1 << 1,
UIPrinterJobTypeLabel = 1 << 2,
UIPrinterJobTypePhoto = 1 << 3,
UIPrinterJobTypeReceipt = 1 << 4,
UIPrinterJobTypeRoll = 1 << 5,
UIPrinterJobTypeLargeFormat = 1 << 6,
UIPrinterJobTypePostcard = 1 << 7
};

@end
5 changes: 5 additions & 0 deletions test/Interop/Cxx/enum/Inputs/module.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ module TypedUntypedEnums {
header "typed-untyped-enums.h"
requires cplusplus
}

module CenumsNSOptionsExternC [extern_c] {
header "c-enums-NS_OPTIONS_without_extern_C.h"
requires cplusplus
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// RUN: %empty-directory(%t/cache)
// RUN: %target-swift-frontend %s -swift-version 5 -I %S/Inputs -typecheck -module-cache-path %t/cache -enable-experimental-cxx-interop 2>&1 | %FileCheck --allow-empty %s

// REQUIRES: objc_interop

import CenumsNSOptionsExternC

// CHECK-NOT: warning: imported declaration '' could not be mapped to 'UIPrinter.JobTypes'
// CHECK-NOT: note: please report this issue to the owners of 'CenumsNSOptions'

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// RUN: %empty-directory(%t/cache)
// RUN: %target-swift-frontend %s -swift-version 5 -I %S/Inputs -typecheck -module-cache-path %t/cache -enable-experimental-cxx-interop 2>&1 | %FileCheck --allow-empty %s

// REQUIRES: objc_interop

import CenumsNSOptions

// CHECK-NOT: warning: imported declaration '' could not be mapped to 'UIPrinter.JobTypes'
// CHECK-NOT: note: please report this issue to the owners of 'CenumsNSOptions'